【问题标题】:Finding and labelling candidates/ouliers outside a curve in R plot在 R 图中查找和标记曲线外的候选/异常值
【发布时间】:2015-01-23 14:44:31
【问题描述】:

我陷入了简单的问题。我有一个散点图。 我使用我的自定义公式在它周围绘制了置信线。现在,我只希望截止线之外的名称在内部不显示任何内容。但是,我不知道如何根据线坐标对数据进行子集化。

线是使用lines函数绘制的,该函数是128个x和y值的向量。现在,我如何根据这两个值对我的数据(x,y 点)进行子集化。我可以对单个子设置数据(例如 1,2 或 3)应用静态限制,但是如何使用向量来子集数据,让我卡住了。

对于可重现的示例,请考虑:

df=data.frame(x=seq(2,16,by=2),y=seq(2,16,by=2),lab=paste("label",seq(2,16,by=2),sep=''))
plot(df[,1],df[,2])

# adding lines
lines(seq(1,15),seq(15,1),lwd=1, lty=2)

# adding labels
text(df[,1],df[,2],labels=df[,3],pos=3,col="red",cex=0.75)

现在,我只需要标签,它们位于线之外或与线相交。

我试图用用于线条的值对我的数据框进行子集化,但我无法做到这一点。

现在,可以对单个值进行静态子设置,例如 df[which(df[,1]>8 & df[,2]>8),] 但如何为整个列表执行此操作。

我也尝试过 sapply,循环遍历用于 df 上的行的所有 x 和 y 值,但大多数值变为 +ve 表示限制,而其他值则变为 false。

谢谢

【问题讨论】:

  • 到目前为止你尝试过什么? minimal reproducible example 也不错。这将使其他人更容易帮助您。
  • 对了,我赶紧加。谢谢

标签: r plot limit subset outliers


【解决方案1】:

我将谈论您最初的火山类型图问题,而不是虚构的问题,因为它们完全不同。

所以我真的想了很多,我相信我得出了一个可靠的结论。有两种选择: 1. 你知道直线的方程,这很容易处理。 2. 你不知道直线的方程,这意味着我们需要使用近似值。

一些几何图形:

函数 显示直线方程。对于给定的坐标对 (x, y),如果 y > 当您传入 x 时等式的右侧,则该点位于直线上方,否则位于直线下方。如果您有曲线(如您的情况),则同样的概念也成立。

如果您有方程式,那么很容易在下面的代码中执行上述操作,并且您已设置好。如果不是,您需要对曲线进行近似。为此,您将需要以下代码:

df=data.frame(x=seq(2,16,by=2),y=seq(2,16,by=2),lab=paste("label",seq(2,16,by=2),sep=''))

make_vector <- function(df) {  
lab <- vector()
for (i in 1:nrow(df)) {
  this_row <- df[i,]  #this will contain the three elements per row
  if ( (this_row[1] < max(line1x) & this_row[2] > max(line1y) & this_row[2] < a + b*this_row[1]) 
        |
        (this_row[1] > min(line2x) & this_row[2] > max(line2y) & this_row[2] > a + b*this_row[1]) ) {
    lab[i] <- this_row[3]
  } else {
    lab[i] <- <NA>
  }
}  
return(lab)
}
#this_row[1] = your x
#this_row[2] = your y
#this_row[3] = your label



df$labels <- make_vector(df)


plot(df[,1],df[,2])

# adding lines
lines(seq(1,15),seq(15,1),lwd=1, lty=2)

# adding labels
text(df[,1],df[,2],labels=df[,4],pos=3,col="red",cex=0.75)

重要的是功能。想象一下,当你用 x,y 和 labs 创建它时,你有 df。您还将有一个向量,其中 line1 的 x,y 坐标和 line2 的 x,y 坐标。

我们只看line1的情况(上面代码实现的line 2也是一样的):

this_row[1] < max(line1x) & this_row[2] > max(line1y) & this_row[2] < a + b*this_row[1]
#translates to:
#this_row[1] < max(line1x) = your x needs to be less than the max x (vertical line in graph below
#this_row[2] > max(line1y) = your y needs to be greater than the max y (horizontal line in graph below
#this_row[2] < a + b*this_row[1] = your y needs to be less than the right hand side of the equation (to have a point above i.e. left of the line) 
#check below what the line is

这将产生类似于下图的效果(这有点可怕,也被放大了,但它只是一个参考。可视化它接近你的线条):

上面的代码会选择三角形上方区域和 y=1 和 x=1 线内的所有点。

最后等式:

拥有 2 个点的坐标,您可以计算出一条线的方程,求解一个由两个方程和 2 个参数 a 和 b 组成的系统。 (y = a +bx 通过替换每个点的 y,x)

要选取的 2 个点是最接近第一条线 (line1) 的切线的两个点。根据您的数据任意选择。越接近切线越好。只需绘制斑点和眼球。

完成上述所有操作后,您的标签就有了您的观点(至少大约如此)。

这是你唯一能做的!

长篇大论,但希望对您有所帮助。

附:我没有测试代码,因为我没有数据。

【讨论】:

  • 不,问题是子集而不是绘图。您没有做对,您使用值 8 进行了子集化,但是有一个包含 15 个元素的向量。所以,像这样df$labels[which(df[,1]&gt;seq(1,15) &amp; df[,2]&gt;seq(1,15))] :)
  • 我没有得到测试。条件测试将如何进行? df[,1] 的每个元素对 seq(1,15) 的每个元素? 1对1?我想这可能就是你的意思。这是有道理的。
  • 不,对不起,我还是不明白....你需要解释一下你希望测试是什么。
  • 是的,没错,这是我的问题,如何解决这个问题,如何测试它。它不能用 seq(1,15) 测试 df[,1] 的每个元素,因为 df[,1] 的所有元素对于 seq(1,15) 的第一个元素可能都是正确的,并且随着 seq(1,15) 的增加而下降元素的值。如果您认为这个问题与第一个情节有关,那似乎很复杂。
  • 好的,我想标记曲线外部而不是内部的点。现在曲线是一个点向量,我想根据曲线点对我的数据框进行子集化,任何我想要的外部。所以,为此我们需要限制,所以要么我将用于构造曲线的点向量转换为单个值限制,然后将我的数据集子集化,这很容易但不是动态的。你会如何处理这个问题?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-17
  • 2013-07-17
  • 2021-11-06
  • 2020-08-27
  • 2016-03-24
  • 1970-01-01
  • 2018-08-30
相关资源
最近更新 更多