在另一列中指定了编号的列上进行过滤

时间:2019-07-09 12:03:14

标签: r dataframe dplyr

我正在寻找一种更好的方法来实现下面的代码通过for循环执行的操作。目标是创建一个数据帧(或矩阵),其中每一行都是n1 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所在的列。

1 个答案:

答案 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)