我想基于应用于其中一列的条件对data.table dat
进行子集化,从而生成子集foobar
,然后使用foobar
作为子集条件所有列上的dat;冲洗并重复,直到子集为空或经过多次迭代。
以下MWE,其中输入和输出作为注释嵌入,是我当前的解决方案。我想知道是否有更快,更好的内存效率和更紧凑的数据。可行的方法来做到这一点。
library(data.table)
dat <- data.table(c("a", "a", "", "b", "b", "c", "d"),
c(1, 1, 1, 1, 2, 3, 4),
c(11, 11, 11, 11, 12, 12, 14),
i = 1:7)
# print(dat)
# input
# V1 V2 V3 i
# 1: a 1 11 1
# 2: a 1 11 2
# 3: 1 11 3
# 4: b 1 11 4
# 5: b 2 12 5
# 6: c 3 12 6
# 7: d 4 14 7
foobar <- dat[V1 == "a" | V2 == 1 | V3 == -1]
for (i in 1:5) {
baz <- dat[!(i %in% foobar$i) & (V1 %chin% foobar$V1 | V2 %in% foobar$V2 | V3 %in% foobar$V3)]
if (nrow(baz) == 0) break
foobar <- rbindlist(list(foobar, baz))
}
# print(foobar)
# output
# V1 V2 V3 i
# 1: a 1 11 1
# 2: a 1 11 2
# 3: 1 11 3
# 4: b 1 11 4
# 5: b 2 12 5
# 6: c 3 12 6
答案 0 :(得分:1)
以下是使用递归执行此操作的方法。我试图使用你已经使用的相同变量名称......
foo <- dat[V1 == "a" | V2 == 1 | V3 == -1]
counter <- 5
special <- function(dat, foobar, counter) {
if (counter > 0 & nrow(foobar) > 0) {
baz <- dat[!(i %in% foobar$i) & (V1 %chin% foobar$V1 | V2 %in% foobar$V2 | V3 %in% foobar$V3)]
special(dat, rbindlist(list(foobar,baz)), counter-1)
} else {
return(foobar)
}
}
注意递归调用是
special(dat, rbindlist(list(foobar,baz)), counter-1)
更新迭代值和foobar
。如果counter==0
或foobar
为空
return(foobar)