объединение значений из строк на основе критериев - PullRequest
0 голосов
/ 17 мая 2018

У меня есть фрейм данных df (см. Код ниже), который содержит около 100 000 строк, отображающих список контактов моей программы. В списке есть столбец, показывающий программу program и организацию O_ID, с которой связан контакт, и столбец для роли, которую контакт имеет в программе. Когда контакт находится в более чем одной программе или имеет более одной роли в программе, для этого контакта создается другая строка с изменением значений поля программы и роли роли.

First   Last    C_ID    OrgName O_ID Program    Role
John    Smith   10045   Acme    901 Buildings   Primary
John    Smith   10045   Acme    901 Buildings   Communications
John    Smith   10045   Acme    901 Homes       Primary
Teddy   Bush    10046   Acme    901 Buildings   Primary
Teddy   Bush    10046   Acme    901 Buildings   Signatory
Jess    Clinton 10050   Consult 904 Homes       Signatory
Jess    Clinton 10050   Consult 904 Homes       Primary
Jess    Clinton 10050   Consult 904 Homes       Communications

В целях презентации я стараюсь минимизировать количество строк. В частности, если контакт находится в той же организации и в той же программе, я хочу, чтобы контакт отображался только в одной строке (в отличие от нескольких в данный момент) и объединял роли контакта в одну строку.

Я попробовал этот код, и он частично работает: ddply(df,.(df$C_ID, df$Program, df$O_ID), paste, sep=",")

Вот результаты:

df$C_ID df$Program df$O_ID                        V1                                 V2
1       10045      Buildings         901         c("John", "John")                c("Smith", "Smith")
2       10045          Homes         901                      John                              Smith
3       10046      Buildings         901       c("Teddy", "Teddy")                  c("Bush", "Bush")
4       10050          Homes         904 c("Jess", "Jess", "Jess") c("Clinton", "Clinton", "Clinton")
                      V3                                 V4               V5                           V6
1        c(10045, 10045)                  c("Acme", "Acme")      c(901, 901)  c("Buildings", "Buildings")
2                  10045                               Acme              901                        Homes
3        c(10046, 10046)                  c("Acme", "Acme")      c(901, 901)  c("Buildings", "Buildings")
4 c(10050, 10050, 10050) c("Consult", "Consult", "Consult") c(904, 904, 904) c("Homes", "Homes", "Homes")
                                           V7
1              c("Primary", "Communications")
2                                     Primary
3                   c("Primary", "Signatory")
4 c("Signatory", "Primary", "Communications")

Проблема в

1) Столбцы были переставлены (обратите внимание, что в моем фактическом наборе данных есть еще много столбцов), и имена столбцов исчезли

2) Единственный столбец с измененными значениями должен находиться в столбце Role. Однако результаты объединяют значения для большинства столбцов, даже если объединенные значения совпадают. Например, в столбце результатов V1 (первый столбец имени) возвращается c("John", "John"). Надо просто прочитать «Джон». Единственный столбец, который должен иметь разные значения, будет столбец V7 c("Primary", "Communications")

df<-structure(list(First = c("John", "John", "John", "Teddy", "Teddy", 
"Jess", "Jess", "Jess"), Last = c("Smith", "Smith", "Smith", 
"Bush", "Bush", "Clinton", "Clinton", "Clinton"), C_ID = c(10045L, 
10045L, 10045L, 10046L, 10046L, 10050L, 10050L, 10050L), OrgName = c("Acme", 
"Acme", "Acme", "Acme", "Acme", "Consult", "Consult", "Consult"
), O_ID = c(901L, 901L, 901L, 901L, 901L, 904L, 904L, 904L), 
    Program = c("Buildings", "Buildings", "Homes", "Buildings", 
    "Buildings", "Homes", "Homes", "Homes"), Role = c("Primary", 
    "Communications", "Primary", "Primary", "Signatory", "Signatory", 
    "Primary", "Communications")), .Names = c("First", "Last", 
"C_ID", "OrgName", "O_ID", "Program", "Role"), class = "data.frame", row.names = c(NA, 
-8L))

Ответы [ 2 ]

0 голосов
/ 17 мая 2018

Вы можете сделать это, используя dplyr.

> df %>% distinct(First, Last, .keep_all=T)
  First    Last  C_ID OrgName O_ID   Program      Role
1  John   Smith 10045    Acme  901 Buildings   Primary
2 Teddy    Bush 10046    Acme  901 Buildings   Primary
3  Jess Clinton 10050 Consult  904     Homes Signatory
0 голосов
/ 17 мая 2018

То, что вам нужно в paste, это collapse = ", ", а не sep.Использование collapse создает одну строку из всех входов.Я делаю это, группируя все идентифицирующие столбцы - имена, организации, программы и т. Д. - и затем сворачивая роли в summarise.

library(tidyverse)

df %>%
  group_by(First, Last, C_ID, OrgName, O_ID, Program) %>%
  summarise(roles_mult = paste(Role, collapse = ", "))
#> # A tibble: 4 x 7
#> # Groups:   First, Last, C_ID, OrgName, O_ID [?]
#>   First Last     C_ID OrgName  O_ID Program   roles_mult                  
#>   <chr> <chr>   <int> <chr>   <int> <chr>     <chr>                       
#> 1 Jess  Clinton 10050 Consult   904 Homes     Signatory, Primary, Communi…
#> 2 John  Smith   10045 Acme      901 Buildings Primary, Communications     
#> 3 John  Smith   10045 Acme      901 Homes     Primary                     
#> 4 Teddy Bush    10046 Acme      901 Buildings Primary, Signatory
...