Объединить строки на основе нескольких столбцов и сохранить все уникальные значения - PullRequest
0 голосов
/ 14 декабря 2018

У меня есть набор данных с информацией о пользователе.Для конкретного пользователя у меня часто несколько строк с более или менее полной информацией.Я хочу суммировать все строки, принадлежащие клиенту, на основе First_Name, Last_Name, Street, сохраняя при этом всю информацию о других столбцах, и, если есть два уникальных наблюдения для конкретного столбца, я хочу свернуть их с помощью ",".

Вот как выглядит df

First_Name Last_Name Street Column1 Colum2 Colum_n

Mike       Smith      X     abc     ab     a
Mike       Smith      X     abc     ad     b
John       Smith      Y     xyz     xy     n
John       Smith      Y     xyz     xm     NA

Мой желаемый результат будет

 First_Name Last_Name Street Column1 Colum2 Colum_n

 Mike       Smith      X     abc     ab,ad     a,b
 John       Smith      Y     xyz     xy,xm       n

Я хотел бы использовать dplyr и попробовать что-то с

df %>% 
group_by(First_Name,Last_Name, Street) %>%
summarise_all(funs())

Проблема с этой функцией заключается в том, что у меня была возможность использовать только что-то вроде среднего значения или первого встречающегося значения для столбца, и это означало бы потерю значений.То, что я хотел бы, это столбцы со всеми уникальными значениями без NA

Ответы [ 4 ]

0 голосов
/ 14 декабря 2018

Использование tidyverse:

df %>%
 group_by(First_Name, Last_Name, Street) %>%
 summarise_all(funs(paste0(unique(.[!is.na(.)]), collapse= ",")))

  First_Name Last_Name Street Column1 Colum2 Colum_n
  <fct>      <fct>     <fct>  <chr>   <chr>  <chr>  
1 John       Smith     Y      xyz     xy,xm  n      
2 Mike       Smith     X      abc     ab,ad  a,b 

Во-первых, это группировка по «First_Name», «Last_Name» и «Street».Затем он принимает все уникальные значения, отличные от NA, и объединяет их в одну строку.

0 голосов
/ 14 декабря 2018

Решение, использующее tidyverse.

library(tidyverse)

dat2 <- dat %>%
  group_by(First_Name, Last_Name, Street) %>%
  # Replace NA with ""
  mutate_all(funs(replace(., is.na(.), ""))) %>%
  # Combine all strings
  summarize_all(funs(toString(unique(.)))) %>%
  # Replace the strings ended with ", "
  mutate_all(funs(str_replace(., ", $", ""))) %>%
  ungroup()
dat2
# # A tibble: 2 x 6
#   First_Name Last_Name Street Column1 Colum2 Colum_n
#   <chr>      <chr>     <chr>  <chr>   <chr>  <chr>  
# 1 John       Smith     Y      xyz     xy, xm n      
# 2 Mike       Smith     X      abc     ab, ad a, b    

Увидев ответ других, я понял, что нам не нужно иметь дело с NA и , как строками.Следующее является более эффективным:

dat2 <- dat %>%
  group_by(First_Name, Last_Name, Street) %>%
  # Combine all strings
  summarize_all(funs(toString(unique(.[!is.na(.)])))) %>%
  ungroup()
dat2
# # A tibble: 2 x 6
#   First_Name Last_Name Street Column1 Colum2 Colum_n
#   <chr>      <chr>     <chr>  <chr>   <chr>  <chr>  
# 1 John       Smith     Y      xyz     xy, xm n      
# 2 Mike       Smith     X      abc     ab, ad a, b  

DATA

dat <- read.table(text = 'First_Name Last_Name Street Column1 Colum2 Colum_n
Mike       Smith      X     abc     ab     a
Mike       Smith      X     abc     ad     b
John       Smith      Y     xyz     xy     n
John       Smith      Y     xyz     xm     NA',
                  header = TRUE, stringsAsFactors = FALSE)
0 голосов
/ 14 декабря 2018

Если вы хотите сохранить их как вектор, вместо преобразования их в одну строку символов, вы можете сделать

library(dplyr)

df %>% 
  group_by(First_Name,Last_Name, Street) %>%
  summarise_all(~list(unique(.[!is.na(.)]))) %>% 
  print.data.frame

#   First_Name Last_Name Street Column1 Colum2 Colum_n
# 1       John     Smith      Y     xyz xy, xm       n
# 2       Mike     Smith      X     abc ab, ad    a, b

или с data.table

library(data.table)
setDT(df)

df[, lapply(.SD, function(x) .(unique(x[!is.na(x)])))
   , by = .(First_Name,Last_Name, Street)]

#    First_Name Last_Name Street Column1 Colum2 Colum_n
# 1:       Mike     Smith      X     abc  ab,ad     a,b
# 2:       John     Smith      Y     xyz  xy,xm       n
0 голосов
/ 14 декабря 2018

Вы можете написать свою собственную функцию суммирования, например

concat_unique <- function(x){paste(unique(x), collapse=',')}

, а затем применить ее, используя summarize_all(concat_unique)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...