Возврат списка в dplyr mutate()
У меня есть функция в моей реальной проблеме, которая возвращает список. Есть ли способ использовать это с dplyr mutate()? Этот игрушечный пример не работает -:
it = data.table(c("a","a","b","b","c"),c(1,2,3,4,5), c(2,3,4,2,2))
myfun = function(arg1,arg2) {
temp1 = arg1 + arg2
temp2 = arg1 - arg2
list(temp1,temp2)
}
myfun(1,2)
it%.%mutate(new = myfun(V2,V3))
Я вижу, что он циклически перебирает выходные данные функции в первом "столбце" новой переменной, но не понимаю, почему.
Спасибо!
2 ответа
Идиоматический способ сделать это с помощью data.table
будет использовать :=
(назначение по ссылке) оператор. Вот иллюстрация:
it[, c(paste0("V", 4:5)) := myfun(V2, V3)]
Если вы действительно хотите список, почему бы и нет:
as.list(it[, myfun(V2, V3)])
Или, может быть, это то, что вы хотите, но почему бы вам просто не использовать data.table
функциональность:
it[, c(.SD, myfun(V2, V3))]
# V1 V2 V3 V4 V5
# 1: a 1 2 3 -1
# 2: a 2 3 5 -1
# 3: b 3 4 7 -1
# 4: b 4 2 6 2
# 5: c 5 2 7 3
Обратите внимание, что если myfun
должны были назвать его вывод, тогда имена будут отображаться в столбцах окончательного результата:
# V1 V2 V3 new.1 new.2
# 1: a 1 2 3 -1
# 2: a 2 3 5 -1
# 3: b 3 4 7 -1
# 4: b 4 2 6 2
# 5: c 5 2 7 3
Учитывая название на этот вопрос, я думал, что выложу tidyverse
решение, которое использует dplyr::mutate
, Обратите внимание, что myfun
необходимо вывести data.frame
работать.
library(tidyverse)
it = data.frame(
v1 = c("a","a","b","b","c"),
v2 = c(1,2,3,4,5),
v3 = c(2,3,4,2,2))
myfun = function(arg1,arg2) {
temp1 = arg1 + arg2
temp2 = arg1 - arg2
data.frame(temp1, temp2)
}
it %>%
nest(v2, v3) %>%
mutate(out = map(data, ~myfun(.$v2, .$v3))) %>%
unnest(data, out)
Функция mutate() предназначена для добавления новых столбцов в существующий фрейм данных. Кадр данных представляет собой список векторов одинаковой длины. Таким образом, вы не можете добавить список в качестве нового столбца, потому что список не является вектором.
Вы можете переписать вашу функцию как две функции, каждая из которых возвращает вектор. Затем примените каждый из них отдельно, используя mutate(), и он должен работать.