使用data_frame作为mutate和group_by例程的参数

时间:2016-10-11 21:56:45

标签: r dplyr

这里有这个data_frame(db),包含很多列:

A  B   C   D ...      ZZ
1  .23 .21   ...      .23
2  .45 .12   ...      .23
1  .47  ...          .53
2  .49  ...          .27

我想使用group_by和mutate来获取一个完整的data_frame并返回一个向量的函数。

function1 <- function(data_frame) {
    ...
    return(vector)
}
db %>%
    group_by(A) %>%
    mutate(results = function1(.))

这不起作用。它返回使用整个data_frame的函数的结果,而不是组。

我知道我可以使用for来解决它,但我正在寻找一个dplyr解决方案。该函数必须获取data_frame,我不会将列分别作为参数传递。

1 个答案:

答案 0 :(得分:1)

dplyr

我的诀窍是使用bind_cols。它本身不会尊重任何组,因此您需要将其嵌套在do块中,例如:

library(dplyr)
mtcars %>%
    group_by(cyl) %>%
    do(bind_cols(., {
        # "insert complex stuff here"
        data_frame(results = apply(., 1, mean))
    }))
# Source: local data frame [32 x 12]
# Groups: cyl [3]
#      mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb  results
#    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>    <dbl>
# 1   22.8     4 108.0    93  3.85 2.320 18.61     1     1     4     1 23.59818
# 2   24.4     4 146.7    62  3.69 3.190 20.00     1     0     4     2 24.63455
# 3   22.8     4 140.8    95  3.92 3.150 22.90     1     0     4     2 27.23364
# # ... with 29 more rows

这种方法的好处是块中的代码可以返回 一个或多个 列,而不会出现进一步的复杂化。

因此,使用您的代码,它看起来像:

db %>%
    group_by(A) %>%
    do(bind_cols(., data_frame(results = function(.))))

tidyr

另一种选择是使用tidy(RStudio blog here,虽然有点过时但它仍然有用。)

library(tidyr) # nest, unnest
library(purrr) # map
mtcars %>%
    group_by(cyl) %>%
    nest() %>%
    mutate(results = map(data, ~ apply(., 1, mean))) %>%
    unnest()

您的代码可能类似于(未经测试):

db %>%
    group_by(A) %>%
    nest() %>%
    mutate(results = purrr::map(data, ~ function1(.))) %>%
    unnest()