R - подмножество строк строками в другом фрейме данных - PullRequest
0 голосов
/ 11 октября 2019

Допустим, у меня есть фрейм данных df, содержащий только факторы / категориальные переменные. У меня есть еще один фрейм данных conditions, где каждая строка содержит различную комбинацию различных уровней факторов некоторого подмножества переменных в df (созданных с использованием expand.grid и levels и т. Д.). Я пытаюсь найти способ поднабора df на основе каждой строки conditions. Так, например, если имена столбцов conditions равны c("A", "B", "C"), а первая строка - c('a1', 'b1', 'c1'), тогда я хочу df[df$A == 'a1' & df$B == 'b1' & df$C == 'c1',] и т. Д.

Ответы [ 2 ]

1 голос
/ 12 октября 2019

Я думаю, что сейчас самое время использовать 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= становится проще.)

1 голос
/ 11 октября 2019

Один из вариантов - создать условие с помощью 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,]
.
...