我正在寻找一种更好的方法来实现下面的代码通过for
循环执行的操作。目标是创建一个数据帧(或矩阵),其中每一行都是n
和1
s的可能的0
长度序列,后跟第n+1
列其中包含与前面的列之一相对应的数字,其中包含0
。
例如,在n == 3
情况下,我们希望包括这样的行:
1 0 0 2
但不是这样:
1 0 0 1
这是我现在拥有的代码(为简单起见,假设使用n == 3
)
library(tidyverse)
df <- expand.grid(x = 0:1, y = 0:1, z = 0:1, target = 1:3, keep = FALSE)
for (row in 1:nrow(df)) {
df$keep[row] <- df[row, df$target[row]] == 0
}
df <- df %>%
filter(keep == TRUE) %>%
select(-keep)
head(df)
# x y z target
# 1 0 0 0 1
# 2 0 1 0 1
# 3 0 0 1 1
# 4 0 1 1 1
# 5 0 0 0 2
# 6 1 0 0 2
# 7 0 0 1 2
# 8 1 0 1 2
# 9 0 0 0 3
# 10 1 0 0 3
# 11 0 1 0 3
# 12 1 1 0 3
似乎必须有一种更好的方法来做到这一点,尤其是对于dplyr
。但是我不知道如何使用target
的值来指定列filter
所在的列。
答案 0 :(得分:1)
使用基数R,我们可以创建行/列索引以从数据框中过滤值,并保留提取的值为0的行。
df[df[cbind(seq_len(nrow(df)), df$target)] == 0, ]
# x y z target
#1 0 0 0 1
#3 0 1 0 1
#5 0 0 1 1
#7 0 1 1 1
#9 0 0 0 2
#10 1 0 0 2
#13 0 0 1 2
#14 1 0 1 2
#17 0 0 0 3
#18 1 0 0 3
#19 0 1 0 3
#20 1 1 0 3
数据
df <- expand.grid(x = 0:1, y = 0:1, z = 0:1, target = 1:3)