Использование пользовательской функции в R DataFrame с dplyr

#r #function #paste #dplyr

#r #функция #вставить #dplyr

Вопрос:

В dplyr можно использовать пользовательскую функцию. Но если я использую следующий код:

 create_string <- function(n) {
 new_string <- paste(c(0:n), collapse=';')
 return(new_string)
}

df <- data.frame(x = 1:3, number = c('4', '2', '1'), expected = c(create_string(4), create_string(2), create_string(1)))

df %>% mutate(reality = create_string(number))
  

Результат равен:

   x number  expected   reality
1 1      4 0;1;2;3;4 0;1;2;3;4
2 2      2     0;1;2 0;1;2;3;4
3 3      1       0;1 0;1;2;3;4
Warning messages:
1: Problem with `mutate()` input `reality`.
i numerical expression has 3 elements: only the first used
i Input `reality` is `create_string(number)`. 
2: In 0:n : numerical expression has 3 elements: only the first used
  

Таким образом, вы можете видеть, что ожидаемый результат не соответствует действительности (включая ошибки)

Ответ №1:

Проблема в том, что mutate заполняет это для всех строк одновременно, что означает create_string(4) , что вы на самом деле получаете create_string(c(4,2,1)) unstad of . Решение состоит в том, чтобы каким-то образом заставить выполнение выполняться по одному значению за раз.

 df %>%
  mutate(reality = sapply(number, create_string))
#   x number  expected   reality
# 1 1      4 0;1;2;3;4 0;1;2;3;4
# 2 2      2     0;1;2     0;1;2
# 3 3      1       0;1       0;1
  

Альтернативы:

 df %>%
  rowwise() %>%
  mutate(reality = create_string(number)) %>%
  ungroup()

df %>% mutate(reality = purrr::map_chr(number, create_string))
df %>% mutate(reality = Vectorize(create_string)(number))
  

Или вы можете векторизовать свою функцию внутри:

 create_string <- function(n) {
 new_string <- sapply(n, function(n0) paste(c(0:n0), collapse=';'))
 return(new_string)
}
df %>%
  mutate(reality = create_string(number))
#   x number  expected   reality
# 1 1      4 0;1;2;3;4 0;1;2;3;4
# 2 2      2     0;1;2     0;1;2
# 3 3      1       0;1       0;1