Объедините несколько столбцов в вектор за строкой с помощью dplyr - PullRequest
1 голос
/ 10 марта 2020

Я пытаюсь объединить несколько столбцов в одну ячейку для каждой строки и затем удалить пропущенные значения.

Пример данных:

df <- data.frame(a=c("a", "b", "c", "d"),
                 b=c(NA, "a", "b", "c"),
                 c=c("a", "b", "e", "g"))

Попытка:

df %>% rowwise() %>%
mutate(collapse=as.character(paste(a,b,c, collapse=",")),
       collapse_nona=na.omit(collapse))

Вывод:

# A tibble: 4 x 5
  a     b     c     collapse                collapse_nona         
* <fct> <fct> <fct> <chr>                   <chr>                 
1 a     NA    a     a NA a,b a b,c b e,d c… a NA a,b a b,c b e,d …
2 b     a     b     a NA a,b a b,c b e,d c… a NA a,b a b,c b e,d …
3 c     b     e     a NA a,b a b,c b e,d c… a NA a,b a b,c b e,d …
4 d     c     g     a NA a,b a b,c b e,d c… a NA a,b a b,c b e,d …

1) Я не могу создать ячейки со значениями для каждой строки (весь столбец отображается в свернутом виде).

2) Ячейки в столбце свертывания не ведут себя как вектор.

Желаемый результат

  a     b     c     collapse                collapse_nona         
* <fct> <fct> <fct> <chr>                   <chr>                 
1 a     NA    a     a NA a                  a a
2 b     a     b     b a b                   b a b
3 c     b     e     c b e                   c b e
4 d     c     g     d c g                   d c g

Спасибо

Ответы [ 3 ]

2 голосов
/ 10 марта 2020

Основная проблема в том, что вы не хотите collapse, вы хотите sep. Тогда поочередный расчет не нужен. Кроме того, NA будет напечатано как символ, поэтому вы не можете удалить их с помощью na.omit

df %>% 
   mutate(collapse = paste(a,b,c, sep = " "), collapse_nona = gsub("NA", "", collapse))

  a    b c collapse collapse_nona
1 a <NA> a   a NA a          a  a
2 b    a b    b a b         b a b
3 c    b e    c b e         c b e
4 d    c g    d c g         d c g
2 голосов
/ 10 марта 2020

С unite, есть опция для na.rm, и по умолчанию FALSE

library(tidyr)
library(dplyr)
df %>%
   mutate_all(as.character) %>%
   unite(collapse, a, b,c,  remove = FALSE, sep=" ") %>%
   unite(collapse_nona, a, b, c, remove = FALSE, sep=" ", na.rm = TRUE) %>%
   select(names(df), everything())
#   a    b c collapse collapse_nona
#1 a <NA> a   a NA a           a a
#2 b    a b    b a b         b a b
#3 c    b e    c b e         c b e
#4 d    c g    d c g         d c g

Или с paste и str_remove_all (из stringr) - Обратите внимание, что paste/str_c векторизовано, поэтому нет необходимости l oop для каждой строки с rowwise

df %>%
     mutate(collapse = paste(a, b, c), 
            collapse_nona = str_remove_all(collapse,  "\\sNA|NA\\s"))
#  a    b c collapse collapse_nona
#1 a <NA> a   a NA a           a a
#2 b    a b    b a b         b a b
#3 c    b e    c b e         c b e
#4 d    c g    d c g         d c g

Другой вариант - от pmap до l oop для каждого удалите элементы NA с помощью na.omit, а затем paste или str_c (из stringr)

library(dplyr)
library(stringr)
library(purrr)
df %>%
     mutate_all(as.character) %>% 
     mutate(collapse_nona = pmap_chr(., ~ c(...) %>%
                na.omit %>%
                str_c(collapse=" "))) 
#  a    b c collapse_nona
#1 a <NA> a           a a
#2 b    a b         b a b
#3 c    b e         c b e
#4 d    c g         d c g
0 голосов
/ 10 марта 2020

Я думаю, что это делает это. Вы можете поиграть с аргументом sep в str_ c.

library(dplyr)
library(stringr)
df %>% 
  mutate(collapse = str_c(str_replace_na(a), str_replace_na(b), str_replace_na(c), sep = " "),
         collapse_nona = str_c(str_replace_na(a, ""), str_replace_na(b, ""), str_replace_na(c,""), sep = " "))

  a    b c collapse collapse_nona
1 a <NA> a   a NA a          a  a
2 b    a b    b a b         b a b
3 c    b e    c b e         c b e
4 d    c g    d c g         d c g
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...