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

R data.table将函数应用于所有列对,r,data.table,R,Data.table,假设我有一个data.table,例如:(或带有数字和NAs) 实现 及 给出FALSE,因为第六行是S=NA但p=不 现在我的问题。 我想概括一下,检查data.table中的所有对,并打印哪些对是“链接的”。 我更愿意只打印正确的结果,而忽略错误的结果,因为我的realdata.table中的大多数对不会被链接,而且我有550个变量 我尝试过以下代码: temp[, lapply(.SD, function(x) temp[is.na(x), lapply

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

实现

给出FALSE,因为第六行是S=NA但p=不

现在我的问题。 我想概括一下,检查data.table中的所有对,并打印哪些对是“链接的”。
我更愿意只打印正确的结果,而忽略错误的结果,因为我的realdata.table中的大多数对不会被链接,而且我有550个变量

我尝试过以下代码:

temp[, lapply(.SD, function(x) temp[is.na(x), 
                 lapply(.SD, function(y)  all(is.na(y)) )]]
我得到这个错误

错误:在“temp[,lapply(.SD,函数(x)”中出现意外“]” 温度[是na(x), lapply(.SD,函数(y)all(is.na(y))]]

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


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

我们可以尝试使用
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

d1对于成对组合,
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
比如:

并使用方便的
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

难道不可能用data.table完成所有操作吗?(出于速度原因)@skan:的确,所有这些矩阵操作都可能会耗尽内存,但对于550列的情况,我认为应该没有问题。或者,您可以尝试上面的稀疏替代方法--
库(矩阵);sNAtemp=as(NAtemp,“sparseMatrix”):crossprod(sNAtemp)=colSums(sNAtemp)
@skan:如果我理解正确,假设
temp$X=c(真、真、真、纳、纳、假、真、假、纳);temp$Y=c(假、纳、纳、真、真、真、真、假)
,你可以使用,比如说,
NAtemp=is.NA(temp);crossprod(NAtemp[、c(“M”、“S”、“X”)、NAtemp[、c(“P”、“Y”))
并与
colSums(NAtemp[,c(“M”,“S”,“X”)])进行比较。
@skan:关于列中没有NA的情况,你是对的;我错过了它。关于你需要的组合,是否总是有两组或更多组,并且你需要对列组进行成对比较?(我假设
ccc
mycomb
?)可能最快的方法是在将其传递给
crossprod
/
colSums
之前对
NAtemp
进行子集划分。例如,我猜您可以使用
spl=split(colnames(NAtemp),mycomb);crossprod(NAtemp[,spl[[1]],NAtemp[,spl[[2]],drop=FALSE])==colSums(NAtemp[,spl[[1]])
etc..@skan:我认为一个简单的
是.na(temp[,vars_to_change])=!temp[,vars_to_change]
-其中
vars_to_change
是一个向量,包含用
na
替换0的列名-应该足够了。(我认为前面的语法对“data.table”无效)s、 尽管如此;它可能需要调整,或者,如果数据只是真/假/NA结构,您可以将数据强制为“矩阵”)您的解决方案非常紧凑,并且使用data.table,但我不知道为什么当数据有许多列时(我的数据有500列,但即使只有50列,您也可以看到它)@alexis_laz解决方案的速度快了几个数量级。我认为您的第一个代码combn(names(temp))也需要以反转的变量顺序重复。
crossprod(NAtemp)
#  M P S
#M 3 2 2
#P 2 3 3
#S 2 3 5
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
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