問題
まず、以下のようなdata.frameを作成します。
set.seed(2)
df <-
tibble(
group = c('A','A','A','A','B','B','B'),
period = c(1,2,3,4,1,2,3),
unif = runif(7)
)
次に、data.frameを引数とし、data.frameを出力とする自作関数を作成します。この関数をgroup毎に実行し、 出力された結果を縦につなげたdata.frameを得たいとします。
example_func <- function(df) {
num_row <- nrow(df)
df <- df %>%
dplyr::mutate(step = 1)
for (i in 1:(num_row-1)) {
df$step[i+1] <- (df$unif[i] > 0.5) + df$step[i]
}
return(df)
}
解決策
group_splitとmap_dfrを組み合わせることで求めた結果が得られます。
df %>%
dplyr::group_split(group) %>%
purrr::map_dfr(example_func)
# A tibble: 7 × 4
# group period unif step
# <chr> <dbl> <dbl> <dbl>
# 1 A 1 0.185 1
# 2 A 2 0.702 1
# 3 A 3 0.573 2
# 4 A 4 0.168 3
# 5 B 1 0.944 1
# 6 B 2 0.943 2
# 7 B 3 0.129 3
別解
また、以下の方法でも同様の結果が得られます。
df %>%
split(.$group) %>%
purrr::map_dfr(example_func)
df %>%
dplyr::group_nest(group) %>%
dplyr::mutate(data = purrr::map(data, example_func)) %>%
tidyr::unnest(data)
df %>%
dplyr::group_by(group) %>%
dplyr::group_modify(~example_func(.x))
謝辞
本内容は、r-wakalangにて教えていただきました。heavywatalさん、atusyさんありがとうございました。