R data.table将函数应用于所有列对
假设我有一个data.table,例如:(或带有数字和NAs) 实现 及 给出FALSE,因为第六行是S=NA但p=不 现在我的问题。 我想概括一下,检查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
我更愿意只打印正确的结果,而忽略错误的结果,因为我的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