既然你提到了unite,我想展示一个使用separate 的解决方案,unite 的补充。
此解决方案将其保留在 tidyverse 中,这使得逐步了解正在发生的事情变得容易。 @d.b 在评论中的回答完美,紧凑,可能运行得更快,但学习曲线更陡峭,以了解正在发生的事情。使用管道tidyverse 解决方案,您可以运行每一行并查看发生了什么。
这个解决方案先separates 条款,然后用gather将数据从宽数据格式转换为长数据格式,这样我们就可以进行诸如检查和处理NAs和“NA”s,drop_na等操作,然后distinct,仅获取唯一值(每个组具有相同的“id”,即来自同一原始行的项目)。然后,它使用summarise 和paste 回到原始格式,但也可以使用spread 然后unite。 (注意na.rm=TRUE是unitehttps://github.com/tidyverse/tidyr/issues/203即将推出的功能)
来源:我使用了这些方便的 dplyr 和 tidyr 参考表:
https://github.com/rstudio/cheatsheets/raw/master/data-transformation.pdf
https://github.com/rstudio/cheatsheets/raw/master/data-import.pdf 并且我还根据这里的 cmets、问题和答案制定了解决方案:How do I remove NAs with the tidyr::unite function?
# Load packages and data
library(tidyverse)
df = data.frame(n = c(2, 3, 5,10),
s = c("aa;bb;cc", "bb;dd;aa", "NA","xx;nn"),
b = c("aa;bb;cc", "bb;dd;cc", "zz;bb;yy","NA"),
t = c("aa;bb;cc", "bb;dd", "kk", NA))
# Solution
dff <- df %>%
separate(col = "s", into = c("s1", "s2", "s3")) %>%
separate(col = "b", into = c("b1", "b2", "b3")) %>%
separate(col = "t", into = c("t1", "t2", "t3")) %>% # Solution here could be enhanced to take in n columns and put them into however many columns as needed, using map or apply.
rowid_to_column('id') %>%
gather(key, value, -(id:n)) %>%
mutate_at(vars(value), na_if, "NA") %>%
drop_na(value) %>%
group_by(id) %>%
distinct(value, .keep_all = TRUE) %>%
summarise(n = first(n), finalcol = paste(value, collapse = ';')) %>%
ungroup() %>%
select(-id)
#> Warning: Expected 3 pieces. Missing pieces filled with `NA` in 2 rows [3,
#> 4].
#> Warning: Expected 3 pieces. Missing pieces filled with `NA` in 1 rows [4].
#> Warning: Expected 3 pieces. Missing pieces filled with `NA` in 2 rows [2,
#> 3].
dff
#> # A tibble: 4 x 2
#> n finalcol
#> <dbl> <chr>
#> 1 2 aa;bb;cc
#> 2 3 bb;dd;aa;cc
#> 3 5 zz;bb;yy;kk
#> 4 10 xx;nn
由reprex package (v0.2.1) 于 2019 年 3 月 26 日创建