Объединить 3 столбца на основе уникальных значений? - PullRequest
1 голос
/ 26 марта 2019

Я пытаюсь объединить 3 столбца в один.Значения столбца разделены знаком ";"а в новом столбце нужно распаковать все 3 значения столбца и поставить уникальные значения.Я знаю, как выполнить слияние столбца.Но я изо всех сил пытаюсь разархивировать значение строки в 3 столбца и найти уникальное значение и поместить в другой столбец.

Вот фиктивные данные

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") 
df = data.frame(n, s, b,t)

> df
   n        s        b        t
1  2 aa;bb;cc aa;bb;cc aa;bb;cc
2  3 bb;dd;aa bb;dd;cc    bb;dd
3  5       NA zz;bb;yy       kk
4 10    xx;nn       NA       NA

Ожидаемый результат -

> df
   n  finalcol
1  2 aa;bb;cc
2  3 bb;dd;aa;cc
3  5 zz;bb;yy;kk
4 10 xx;nn

Что мне нужно для простого слияния

dff = df %>% unite(finalcol, c(s,b,t), sep = ";", remove = TRUE)

1 Ответ

3 голосов
/ 27 марта 2019

Поскольку вы упомянули unite, я хочу показать решение, используя separate, дополнение к unite.

Это решение удерживает его в пределах tidyverse, что позволяет легко понять, что происходит, шаг за шагом. Ответ @ d.b в комментарии работает отлично, компактен и, вероятно, работает быстрее, но имеет более крутой курс обучения, чтобы понять, что происходит. С помощью конвейерного tidyverse решения вы можете запустить каждую строку и посмотреть, что происходит.

Это решение сначала separate в терминах, затем преобразует данные из широкого в длинный формат данных с помощью gather, чтобы мы могли выполнять такие операции, как проверка и обработка NA и "NA", drop_na и затем distinct, чтобы получить только уникальные значения (для группы с одинаковым «идентификатором», т. е. элементы из той же исходной строки). Затем он использует summarise и paste для возврата к исходному формату, но может также использовать spread, а затем unite. (Обратите внимание, что na.rm=TRUE является следующей функцией unite https://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 и я также разработал решение, основываясь на комментариях, вопросах и ответах здесь: Как удалить NA с помощью функции tidyr :: unite?

# 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

Создано в 2019-03-26 с помощью представительного пакета (v0.2.1)

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