R-另一个数据帧中逐行的子集

最后发布: 2019-10-11 20:42:45


问题

假设我有一个仅包含因子/分类变量的数据框df 我还有另一个数据框conditions ,其中每一行都包含df中某些变量子集的不同因子水平的不同组合(使用expand.gridlevels等)。 我试图找出一种基于每行conditions子集df方法。 因此,例如,如果conditions的列名称为c("A", "B", "C")且第一行为c('a1', 'b1', 'c1') ,则我想要df[df$A == 'a1' & df$B == 'b1' & df$C == 'c1',] ,依此类推。

r subset
回答

一种选择是使用Reduce创建条件

df[Reduce(`&`, Map(`==`, df[c("A", "B", "C")], df[1, c("A", "B", "C")])),]

或另一个选择是rowSums

df[rowSums(df[c("A", "B", "C")] == 
           df[1, c("A", "B", "C")][col(df[c("A", "B", "C")])]) == 3,]


回答

我认为这是使用merge (或dplyr::*_join或...)的好时机:

df1 <- expand.grid(A = letters[1:4], B = LETTERS[1:4], stringsAsFactors = FALSE)
df1$rn <- seq_len(nrow(df1))

# 'df2' contains the conditions we want to filter (retain)
df2 <- data.frame(
  a1 = c('a', 'a', 'c'),
  b1 = c('B', 'C', 'C'),
  stringsAsFactors = FALSE
)

df1
#    A B rn
# 1  a A  1
# 2  b A  2
# 3  c A  3
# 4  d A  4
# 5  a B  5
# 6  b B  6
# 7  c B  7
# 8  d B  8
# 9  a C  9
# 10 b C 10
# 11 c C 11
# 12 d C 12
# 13 a D 13
# 14 b D 14
# 15 c D 15
# 16 d D 16

df2
#   a1 b1
# 1  a  B
# 2  a  C
# 3  c  C

使用df2定义我们需要保留的组合,

merge(df1, df2, by.x=c('A','B'), by.y=c('a1','b1'))
#   A B rn
# 1 a B  5
# 2 a C  9
# 3 c C 11

# or
dplyr::inner_join(df1, df2, by=c(A='a1', B='b1'))

(我用不同的列名定义了df2只是为了展示其工作原理,但实际上,由于其目的是“仅”是要声明要过滤的组合的声明,所以在这种情况下,使用相同的列名对我来说很有意义by=参数变得更简单。)