Как отфильтровать данные, если в группе есть определенные значения? - PullRequest
0 голосов
/ 14 апреля 2020

У меня есть такой набор данных:

VisitID | Item |
1       | A    |
1       | B    |
1       | C    |
1       | D    |
2       | A    |
2       | D    |
2       | B    |
3       | B    |
3       | C    |
4       | D    |
4       | C    |

Я хочу вернуть строки VisitID до тех пор, пока в VisitID встречается элемент A ИЛИ B. Как я могу go узнать? Ожидаемый результат:

VisitID | Item |
1       | A    |
1       | B    |
1       | C    |
1       | D    |
2       | A    |
2       | D    |
2       | B    |
3       | B    |
3       | C    |

Ответы [ 4 ]

4 голосов
/ 14 апреля 2020

В базе R я бы сделал:

df <- data.frame(VisitID = c(1,1,1,1,2,2,2,3,3,4,4), 
                 Item = c("A", "B", "C", "D", "A", "D", "B", "B", "C", "D", "C"))

do.call("rbind", lapply(split(df, df$VisitID), function(x) if(any(x[,2] %in% c("A", "B"))) x else NULL))

# VisitID Item
# 1.1       1    A
# 1.2       1    B
# 1.3       1    C
# 1.4       1    D
# 2.5       2    A
# 2.6       2    D
# 2.7       2    B
# 3.8       3    B
# 3.9       3    C
2 голосов
/ 14 апреля 2020

Еще одно условие фильтрации без группировки данных:

library(dplyr)

df %>%
  filter(VisitID %in% VisitID[Item %in% c('A', 'B')])

#   VisitID Item
# 1       1    A
# 2       1    B
# 3       1    C
# 4       1    D
# 5       2    A
# 6       2    D
# 7       2    B
# 8       3    B
# 9       3    C
2 голосов
/ 14 апреля 2020

Мы можем выбрать группы, в которых any Item имеет либо 'A', либо 'B'.

library(dplyr)
df %>% group_by(VisitID) %>% filter(any(Item %in% c('A', 'B')))

#  VisitID Item 
#    <int> <fct>
#1       1 A    
#2       1 B    
#3       1 C    
#4       1 D    
#5       2 A    
#6       2 D    
#7       2 B    
#8       3 B    
#9       3 C    

Или в базе R:

subset(df, ave(Item %in% c('A', 'B'), VisitID, FUN = any))

и в data.table

library(data.table)
setDT(df)[, .SD[any(Item %in% c('A', 'B'))], VisitID]

data

df <- structure(list(VisitID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 
4L, 4L), Item = structure(c(1L, 2L, 3L, 4L, 1L, 4L, 2L, 2L, 3L, 
4L, 3L), .Label = c("A", "B", "C", "D"), class = "factor")), 
row.names = c(NA, -11L), class = "data.frame")
1 голос
/ 14 апреля 2020

Другое base решение:.

groups <- rowsum(x = as.numeric( df$Item %in% c("A", "B") ), group = df$VisitID)
df[df$VisitID %in% rownames(groups)[groups > 0] , ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...