Почему мутация не действует так, как я ожидаю в этом коде? - PullRequest
1 голос
/ 27 мая 2019

У меня путаница в отношении того, как работает mutate в tidyverse / dplyr.Я включил воспроизводимый пример здесь.Один использует мутирование, а другой - цикл.Я ожидал бы, что оба дадут тот же самый результат, но они не делают.Понятия не имею почему.Мы будем благодарны за любую помощь.

library(tidyverse)
d <- data.frame(x = c('a,a,b,b,b','a,a','a,b,b,b,c,c,c'))
# Approach 1 (mutate)
d %>% 
  mutate(y = paste(unique(str_split(x, ',')[[1]]), collapse = ','))
d
# Approach 2 (loop)
for (i in 1:nrow(d))
{
  d$y[i] <- paste(unique(str_split(d$x[i], ',')[[1]]), collapse = ',')
}
d

Я ожидаю, что результаты будут одинаковыми для обоих подходов, но это не так.

1 Ответ

1 голос
/ 27 мая 2019

Проблема заключается в том, что мы сначала задаем только элемент list с [[1]], а затем unique только для этого элемента.Вместо этого нам нужно пройти через list (из str_split output)

library(tidyverse) 
d %>%
     mutate(y = str_split(x, ',') %>%  # output is a list
                   map_chr(~ unique(.x) %>% # loop with map, get the unique elements 
                    toString)) # paste the strings together
#             x       y
#1     a,a,b,b,b    a, b
#2           a,a       a
#3 a,b,b,b,c,c,c a, b, c

В цикле for это было не так, потому что расщепление было выполнено одним элементом ввремя str_split(d$x[i]


Чтобы лучше понять, str_split (strsplit основание R ) is vectorized. They can take multiple strings and split into a список of векторов равно длине начального вектора

str_split(d$x, ',') # list of length 3
#[[1]]
#[1] "a" "a" "b" "b" "b"

#[[2]]
#[1] "a" "a"

#[[3]]
#[1] "a" "b" "b" "b" "c" "c" "c"

Извлечение первого [[1]]

str_split(d$x, ',')[[1]]
#[1] "a" "a" "b" "b" "b"

В цикле for мы индивидуально разбиваем элементы и извлекаем элемент списка (длина 1)

str_split(d$x[1], ',')[[1]]
#[1] "a" "a" "b" "b" "b"
str_split(d$x[2], ',')[[1]]
#[1] "a" "a"

Именно по этой причине нам нужно перебрать list и затем получить unique от каждого из элементов

...