R как сгруппировать значения столбцов по теории множеств - PullRequest
0 голосов
/ 15 апреля 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 содержит только A, только B, только C, A & B, A & C, B & C, A & B & C, Другие (не существует ни A, B, C)

Результаты должны выглядеть следующим образом:

VisitID | Item | Classification |
1       | A    | A&B&C          |
1       | B    | A&B&C          |
1       | C    | A&B&C          |
1       | D    | A&B&C          |
2       | A    | A&B            |
2       | D    | A&B            |
2       | B    | A&B            |
3       | B    | B&C            |
3       | C    | B&C            |
4       | D    | C only         |
4       | C    | C only         |

Как я могу сделать это в R, особенно с dplyr?

Ответы [ 2 ]

1 голос
/ 15 апреля 2020

Вы можете использовать left_join данных с group_by, отфильтрованным, суммированным.

library(dplyr)

data %>% left_join(
  group_by(data, VisitID) %>%
  distinct(VisitID, Item) %>%
  filter(Item %in% c("A","B","C")) %>%
  summarise(set=paste0(Item, collapse="&")),
  by="VisitID")

Выход:

   VisitID Item   set
1        1    A A&B&C
2        1    B A&B&C
3        1    C A&B&C
4        1    D A&B&C
5        2    A   A&B
6        2    D   A&B
7        2    B   A&B
8        3    B   B&C
9        3    C   B&C
10       4    D     C
11       4    C     C
12       5    D  <NA>
13       5    E  <NA>

Данные : dput (данные)

structure(list(VisitID = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 
4L, 4L, 5L, 5L), Item = c("A", "B", "C", "D", "A", "D", "B", 
"B", "C", "D", "C", "D", "E")), class = "data.frame", row.names = c(NA, 
-13L))
0 голосов
/ 15 апреля 2020

Мы можем написать пользовательскую функцию:

paste_values <- function(x) {
   x1 <- x[x %in% c("A", "B", "C")]
   if (n_distinct(x1) == 1)
   #If want to keep in base R
   #if (length(unique(x1) == 1)
     paste0(unique(x1), " only")
   else
     paste0(unique(x1), collapse = " & ")
}

и применить ее для каждой группы.

library(dplyr)
df %>% group_by(VisitID) %>% mutate(Item = paste_values(Item))

#    VisitID Item     
#     <int> <chr>    
# 1       1 A & B & C
# 2       1 A & B & C
# 3       1 A & B & C
# 4       1 A & B & C
# 5       2 A & B    
# 6       2 A & B    
# 7       2 A & B    
# 8       3 B & C    
# 9       3 B & C    
#10       4 C only   
#11       4 C only   

Мы также можем использовать ту же функцию в базе R:

df$Item <- with(df, ave(Item, VisitID, FUN = paste_values))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...