Вернуться в список, используя mutate и rowwise
Я пытаюсь вернуть список, используя mutate и rowwise, но получаю ошибку, показанную в коде. Эти вопросы Q1 Q2 помогли, но я хотел бы сделать это простым, перебирая строки, используя rowwise()
и вопросы 3yr 7mth. Благодарю.
library(tidyverse)
df <- data.frame(Name=c("a","a","b","b","c"),X=c(1,2,3,4,5), Y=c(2,3,4,2,2))
TestFn <- function(X,Y){
Z <- list(X*5,Y/2,X+Y,X*2+5*Y)
return (Z)
}
#this works
SingleResult <- TestFn(5,20)
#error - Error in mutate_impl(.data, dots) : incompatible size (4), expecting 1 (the group size) or 1
dfResult <- df %>%
rowwise() %>%
mutate(R=TestFn(X,Y))
2 ответа
Ваш TestFn
возвращает список из 4 элементов в строке, который не может быть помещен в строку; Вы можете сначала обернуть возвращаемые элементы в вектор, чтобы возвращаемый список был одним списком элементов:
TestFn <- function(X, Y) list(c(X*5, Y/2, X+Y, X*2+5*Y))
# ^
df %>% rowwise() %>% mutate(R=TestFn(X,Y)) %>% pull(R)
#[[1]]
#[1] 5 1 3 12
#[[2]]
#[1] 10.0 1.5 5.0 19.0
#[[3]]
#[1] 15 2 7 26
#[[4]]
#[1] 20 1 6 18
#[[5]]
#[1] 25 1 7 20
rowwise
Обычно это не так эффективно, если вы хотите векторизовать решение, вы можете сначала вычислить четыре выражения, а затем транспонировать результат:
df$R = with(df, data.table::transpose(list(X*5, Y/2, X+Y, X*2+5*Y)))
df
# Name X Y R
#1 a 1 2 5, 1, 3, 12
#2 a 2 3 10.0, 1.5, 5.0, 19.0
#3 b 3 4 15, 2, 7, 26
#4 b 4 2 20, 1, 6, 18
#5 c 5 2 25, 1, 7, 20
tidyverse
Теперь вы можете вкладывать сложные структуры данных
Tidyverse решение
df %>%
mutate(copyX = X, copyY = Y) %>%
nest(copyX, copyY) %>%
mutate(data = map(data, ~TestFn(.x$copyX, .x$copyY)))
выход
Name X Y data
<fctr> <dbl> <dbl> <list>
1 a 1 2 <list [4]>
2 a 2 3 <list [4]>
3 b 3 4 <list [4]>
4 b 4 2 <list [4]>
5 c 5 2 <list [4]>
Как преобразовать во фрейм данных?
Так как ваша функция возвращает список, я добавил дополнительный шаг перед unnest
ИНГ
df %>%
mutate(copyX = X, copyY = Y) %>%
nest(copyX, copyY) %>%
mutate(data = map(data, ~TestFn(.x$copyX, .x$copyY))) %>%
mutate(data = map(data, ~unlist(.x))) %>%
unnest(data)
выход
Name X Y data
<fctr> <dbl> <dbl> <dbl>
1 a 1 2 5.0
2 a 1 2 1.0
3 a 1 2 3.0
4 a 1 2 12.0
5 a 2 3 10.0
6 a 2 3 1.5
# etc