我正在尝试使用返回向量的自定义函数dplyr::mutate来group_by数据和创建新列,并且该函数需要很长时间才能引导。
我知道这可以在基础 R 中实现,但是 dplyr 中有更优雅的方法吗?
\n示例(已废弃):
\niris %>% \n group_by(Species) %>% \n mutate(t1 = f(iris$Sepal.Length)[1], t2 = f(iris$Sepal.Length)[2])\n\nf <- function(x) {\n return(c(2*x, x+1))\n}\nRun Code Online (Sandbox Code Playgroud)\n是否可以创建两列,每组中只调用一次该函数?
\n我在前面的示例中犯了一个错误。请检查这个示例:
\n例子:
\nf <- function(x) {\n return(c(x*2, x+1))\n}\n\niris %>% \n group_by(Species) %>% \n \n group_modify(~ {\n .x %>% \n mutate(t1 := f(mean(.x$Sepal.Length))[1], t2 := f(mean(.x$Sepal.Length))[2])\n })\nRun Code Online (Sandbox Code Playgroud)\n方法一:
\n感谢蔡达伦的回答!unnest_wider使用新示例解决了该问题:
library(dplyr)\nlibrary(tidyr)\n\niris %>% \n group_by(Species) %>% \n group_modify(~ {\n .x %>% \n mutate(t = list(f(mean(.x$Sepal.Length)))) %>% \n unnest_wider(t, names_sep = "")\n })\n\n# A tibble: 150 \xc3\x97 7\n# Groups: Species [3]\n Species Sepal.Length Sepal.Width Petal.Length Petal.Width t1 t2\n <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>\n 1 setosa 5.1 3.5 1.4 0.2 10.0 6.01\n 2 setosa 4.9 3 1.4 0.2 10.0 6.01\n 3 setosa 4.7 3.2 1.3 0.2 10.0 6.01\n 4 setosa 4.6 3.1 1.5 0.2 10.0 6.01\n 5 setosa 5 3.6 1.4 0.2 10.0 6.01\n 6 setosa 5.4 3.9 1.7 0.4 10.0 6.01\n 7 setosa 4.6 3.4 1.4 0.3 10.0 6.01\n 8 setosa 5 3.4 1.5 0.2 10.0 6.01\n 9 setosa 4.4 2.9 1.4 0.2 10.0 6.01\n10 setosa 4.9 3.1 1.5 0.1 10.0 6.01\n# \xe2\x80\xa6 with 140 more rows\n# \xe2\x84\xb9 Use `print(n = ...)` to see more rows\nRun Code Online (Sandbox Code Playgroud)\n方法二:
\n感谢康拉德·鲁道夫的建议!更灵活的方式来回答这个问题!
\nto_tibble <- function (x, colnames) {\n x %>%\n matrix(ncol = length(colnames), dimnames = list(NULL, colnames)) %>%\n as_tibble()\n}\niris %>%\n group_by(Species) %>%\n mutate(to_tibble(f(mean(Sepal.Length)), c("t1", "t2")))\nRun Code Online (Sandbox Code Playgroud)\n
您的代码的问题在于它将向量传递给f,因此结果可能不是您所期望的\xe2\x80\x99:
f(1 : 5)\n# [1] 2 4 6 8 10 2 3 4 5 6 \nRun Code Online (Sandbox Code Playgroud)\n您的调用代码必须解决这个问题。
\n您可以这样做,例如使用以下助手:
\nto_tibble <- function (x, colnames) {\n x %>%\n matrix(ncol = length(colnames), dimnames = list(NULL, colnames)) %>%\n as_tibble()\n}\nRun Code Online (Sandbox Code Playgroud)\n这样,您现在可以调用f内部mutate并提供目标列名称:
iris %>%\n group_by(Species) %>%\n mutate(to_tibble(f(Sepal.Length), c("t1", "t2"))\nRun Code Online (Sandbox Code Playgroud)\n这种方法的优点是它简化了调用代码,并mutate利用 \xe2\x80\x99s 的内置支持来生成多个列 \xe2\x80\x94 ,无需手动取消嵌套。
关于更新的代码/要求,您也可以使用辅助函数来简化:
\niris %>%\n group_by(Species) %>%\n mutate(to_tibble(f(Sepal.Length), c("t1", "t2"))\nRun Code Online (Sandbox Code Playgroud)\n