R data.table将函数应用于所有列对

时间:2016-12-27 19:37:59

标签: r data.table

假设我有一个data.table,例如:(或带数字和NA)

temp <- data.table(M=c(NA,T,T,F,F,F,NA,NA,F), 
                   P=c(T,T,T,F,F,F,NA,NA,NA), S=c(T,F,NA,T,F,NA,NA,NA,NA))

    M     P     S
   NA  TRUE  TRUE
 TRUE  TRUE FALSE
 TRUE  TRUE    NA
FALSE FALSE  TRUE
FALSE FALSE FALSE
FALSE FALSE    NA
   NA    NA    NA
   NA    NA    NA
FALSE    NA    NA

我想检查变量是否为NA意味着第二个变量的值都是NA。检查某些变量是否与其他变量相关联。

例如,每当P = NA时,我们也有S = NA。

此代码适用于两个单独的列:

temp[is.na(P),all(is.na(S))]

给出TRUE

temp[is.na(S),all(is.na(P))]

给出FALSE,因为第六行是S = NA但是P!= NA。

现在我的问题。 我想概括一下,检查我的data.table中的所有对,并打印出哪些对&#34;链接&#34;。
我更喜欢只打印TRUE的结果,忽略FALSE的结果,因为我的真实data.table中的大多数对都没有链接,我有550个变量。

我已尝试过此代码:

temp[, lapply(.SD, function(x) temp[is.na(x), 
                 lapply(.SD, function(y)  all(is.na(y)) )]]

我收到此错误

  

错误:意外&#39;]&#39; in:&#34; temp [,lapply(.SD,function(x)   温度[is.na(x)的                                       lapply(.SD,function(y)all(is.na(y)))]]&#34;

我可以尝试使用for循环,但我更喜欢典型的data.table语法。 欢迎提出任何建议。

我还想知道在嵌套data.table调用时如何引用两个不同的.SD。

2 个答案:

答案 0 :(得分:5)

对于成对组合,crossprod似乎仍然有用。

我们只关心值是否为NA

NAtemp = is.na(temp)

比较NA s:

的共存
crossprod(NAtemp)
#  M P S
#M 3 2 2
#P 2 3 3
#S 2 3 5

每列NA的数量:

colSums(NAtemp)
#M P S 
#3 3 5

像:

ans = crossprod(NAtemp) == colSums(NAtemp)
ans
#      M     P     S
#M  TRUE FALSE FALSE
#P FALSE  TRUE  TRUE
#S FALSE FALSE  TRUE

使用方便的as.data.frame.table格式化:

subset(as.data.frame(as.table(ans)), Var1 != Var2)
#  Var1 Var2  Freq
#2    P    M FALSE
#3    S    M FALSE
#4    M    P FALSE
#6    S    P FALSE
#7    M    S FALSE
#8    P    S  TRUE

答案 1 :(得分:3)

我们可以尝试combn

unlist(combn(names(temp), 2, FUN = function(nm)
  list(setNames(temp[is.na(get(nm[1])), all(is.na(get(nm[2])))], paste(nm, collapse="-"))))) 
#   M-P   M-S   P-S 
# FALSE FALSE  TRUE 

或者如果我们还需要所有组合

d1 <- CJ(names(temp), names(temp))[V1!=V2]
d1[,  .(index=temp[is.na(get(V1)), all(is.na(get(V2)))]) , .(V1, V2)]
#    V1 V2 index
#1:  M  P FALSE
#2:  M  S FALSE
#3:  P  M FALSE
#4:  P  S  TRUE
#5:  S  M FALSE
#6:  S  P FALSE