我有一个值数据框,对于数据框中的每个值,我想确定它是否在其行中任何其他值的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
有关最快最好的方式的任何想法都会受到赞赏。
由于
答案 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