Сжать фрейм данных с условиями для определенных столбцов

#r

#r

Вопрос:

У меня есть набор данных, который выглядит следующим образом

 df = data.frame(Site = c(rep('w',4),rep('x',5),rep('y',2),rep('z',1)),
                Parent = c(rep('W Inc.',4),rep('X Inc.',5),rep('Y Inc.',2),rep('Z Inc.',1)),
                Status = c(rep('Prospect',4),rep('Client',5),rep('Client',2),rep('Prospect',1)),
                Country = c(rep('USA',4),rep('Canada',5),rep('Mexico',2),rep('China',1)),
                ProductID = c('XP10','XP11','XP18','XP19','XP4','XP5','XP6','XP7','XP8','XP10','XP18','XP6'),
                ProductName = c('10Rockets','11Rockets','18Rockets','19Rockets','4Rockets','5Rockets','6Rockets','7Rockets','8Rockets','10Rockets','18Rockets','6Rockets'),
                ProductProvider= c('Provider A','Provider B','Provider A','Provider A',rep('Provider A',5),'Provider A','Provider B','Provider B'))
  

Я хотел бы сконденсировать его так, чтобы каждый Site из них был уникальной строкой, а последние 3 столбца были объединены.
Кроме того, я хотел бы объединить последний столбец таким образом, чтобы при наличии каких-либо повторений он принимал только уникальные значения для каждого Site и разделял их запятыми.

Моя попытка

 library(dplyr)
output2 = df %>% group_by(Site,Parent,Status,Country) %>% 
  mutate(ProductID = paste(ProductID, collapse=",")) %>%
  mutate(ProductName = paste(ProductName, collapse=",")) %>%
  mutate(ProductProvider = unique(paste(ProductProvider, collapse=","))) %>%
  distinct()
  

Я почти на месте, но в последнем столбце, похоже, есть повторения ProductProvider , которые я не хочу.

Целевой результат

Я ищу целевой набор данных, подобный этому, с объединением последнего столбца и без каких-либо повторений. Любые входные данные будут оценены.

 output = data.frame(Site = c(rep('w',1),rep('x',1),rep('y',1),rep('z',1)),
                Parent = c(rep('W Inc.',1),rep('X Inc.',1),rep('Y Inc.',1),rep('Z Inc.',1)),
                Status = c(rep('Prospect',1),rep('Client',1),rep('Client',1),rep('Prospect',1)),
                Country = c(rep('USA',1),rep('Canada',1),rep('Mexico',1),rep('China',1)),
                ProductID = c('XP10,XP11,XP18,XP19','XP4,XP5,XP6,XP7,XP8','XP10,XP18','XP6'),
                ProductName = c('10Rockets,11Rockets,18Rockets,19Rockets','4Rockets,5Rockets,6Rockets,7Rockets,8Rockets','10Rockets,18Rockets','6Rockets'),
                ProductProvider= c('Provider A,Provider B','Provider A','Provider A,Provider B','Provider B'))
  

Ответ №1:

С dplyr :

 library(dplyr)
result = df %>% group_by(Site, Parent, Status, Country) %>%
  summarize(across(ProductProvider, ~paste(unique(.), collapse = ", ")),
            across(everything(), paste, collapse = ", "))
result
# # A tibble: 4 x 7
# # Groups:   Site, Parent, Status [4]
#   Site  Parent Status   Country ProductProvider        ProductID               ProductName                                     
#   <chr> <chr>  <chr>    <chr>   <chr>                  <chr>                   <chr>                                           
# 1 w     W Inc. Prospect USA     Provider A, Provider B XP10, XP11, XP18, XP19  10Rockets, 11Rockets, 18Rockets, 19Rockets      
# 2 x     X Inc. Client   Canada  Provider A             XP4, XP5, XP6, XP7, XP8 4Rockets, 5Rockets, 6Rockets, 7Rockets, 8Rockets
# 3 y     Y Inc. Client   Mexico  Provider A, Provider B XP10, XP18              10Rockets, 18Rockets                            
# 4 z     Z Inc. Prospect China   Provider B             XP6                     6Rockets 
  

Комментарии:

1. Ваше решение объединяет все, кроме Site . Я просто хотел объединить последние 3 столбца.

Ответ №2:

Короткий и приятный aggregate .

 aggregate(. ~ Site, df, unique)
#   Site Parent   Status Country               ProductID                                      ProductName        ProductProvider
# 1    w W Inc. Prospect     USA  XP10, XP11, XP18, XP19       10Rockets, 11Rockets, 18Rockets, 19Rockets Provider A, Provider B
# 2    x X Inc.   Client  Canada XP4, XP5, XP6, XP7, XP8 4Rockets, 5Rockets, 6Rockets, 7Rockets, 8Rockets             Provider A
# 3    y Y Inc.   Client  Mexico              XP10, XP18                             10Rockets, 18Rockets Provider A, Provider B
# 4    z Z Inc. Prospect   China                     XP6                                         6Rockets             Provider B
  

Комментарии:

1. Очень элегантное решение! Однако как удалить c («»)..

2. @Varun Что c("") ты имеешь в виду?

3. По какой-то причине, когда я пробую ваш подход, последние три столбца имеют c («»), окружающие каждую запись. Например, строка 1, столбец 5 — это c («XP10», «XP11», «XP18», «XP19») в моей выходной таблице с использованием вашего решения.

4. Я бы предпочел, чтобы это было без скобок и кавычек, если это возможно

5. @Varun Это странно, вы используете обновленную R version 4.0.2 версию?