R:查找值是否在其行中任何其他值的特定百分比内

时间:2014-12-03 11:04:51

标签: r dataframe row percentage

我有一个值数据框,对于数据框中的每个值,我想确定它是否在其行中任何其他值的10%之内。我想这样做一般,因为我不知道我将有多少列,也不知道列的名称。

有些值是NA,如果行中的所有其他值都是NA,我想返回TRUE。对于NA的实际值,我想返回FALSE。值均为正值,但可以为0.

例如说我有以下数据框

dataDF <- data.frame(
                     a = c(100, 250,  NA, 700,   0),
                     b = c(105, 300, 280,  NA,   0),
                     c = c(200, 400, 280,  NA,   0)
                     )

在第一行中,我们得到a = 100,b = 105和c = 200.a和b在彼此的10%之内,所以我们对于这两者都是TRUE,c不在任何一个的10%之内或者b这样就可以了。

在第二行中,没有值在彼此的10%范围内,因此所有值都为FALSE

在第三行中,b和c相等,所以为TRUE,a为NA,因此为FALSE。

在第四行中,我们只有a的值,因此返回为TRUE,b和c为FALSE

在最后一行中,所有值都相同,因此对于所有

,我们将为TRUE

所以我的输出将是

data.frame(
           a = c( TRUE, FALSE, FALSE,  TRUE, TRUE),
           b = c( TRUE, FALSE,  TRUE, FALSE, TRUE),
           c = c(FALSE, FALSE,  TRUE, FALSE, TRUE)
          )

我如何计算百分比差异并不重要,但他们这样做的方法是将绝对差值除以2值的平均值,这样无论我看哪种方式,我都得到相同的值在它。

因此,例如,要计算100到105之间的百分比差异,它将是:

abs(100 - 105)/((100 + 105)/2) = 5/102.5 = 0.0488

有关最快最好的方式的任何想法都会受到赞赏。

由于

1 个答案:

答案 0 :(得分:2)

定义一个函数,将它应用于data.frame的每一行:

fun <- function(vec)
{
  n = length(vec)

  if(all(is.na(vec)))
    return(rep(FALSE,n))

  noNA = vec[!is.na(vec)]

  if(length(unique(noNA))==1)
    return(!is.na(vec))

  res = rep(FALSE, n)

  for(i in 1:n)
    if(any(abs(vec[i]-vec[-i])<=vec[-i]*0.1, na.rm = TRUE))
      res[i] = TRUE

  res
}

output=data.frame(t(apply(dataDF,1,fun)))
names(output) = names(dataDF)
output

给出想要的结果:

#      a     b     c
#1  TRUE  TRUE FALSE
#2 FALSE FALSE FALSE
#3 FALSE  TRUE  TRUE
#4  TRUE FALSE FALSE
#5  TRUE  TRUE  TRUE