根据多列合并行并保留所有唯一值

时间:2018-12-14 14:25:30

标签: r

我有一个包含用户信息的数据集。对于特定的用户,我经常会有多行或多或少包含完整的信息。我想根据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 :(得分:3)

您可以编写自己的汇总功能,例如

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

,然后使用 summarize_all(concat_unique)

答案 1 :(得分:2)

使用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  

数据

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)

答案 2 :(得分:2)

如果您想将它们保留为向量,可以将其转换为单个字符串,而不是

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

答案 3 :(得分:2)

使用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 

首先,按“名字”,“姓氏”和“街道”分组。然后,它获取所有唯一的非NA值并将它们折叠为一个字符串。