这是一个可能的解决方案:
# example data
set.seed(42)
ID <- as.factor(c(rep("A",20),rep("B",22)))
date <- as.factor(c(rep("C",12),rep("D",8),rep("E",10),rep("F",12)))
group <- as.factor(c(rep("G",6),rep("H",6),rep("G",8),rep("G",6),rep("H",4),rep("G",6),rep("H",6)))
val <- round(rnorm(42,20,10),0)
df <- data.frame(ID,date,group,val)
# using the function you provided
f = function(br, df) {aggregate(val~ID+date+group,df,FUN=function(x) table(cut(x, br)))}
library(tidyverse)
# create a look up table
# (specify the breaks for each group)
look_up = data_frame(group_id = c("G","H"),
br = list(c(0,10,30,100), c(0,10,50,100)))
df_upd = df %>%
group_by(group_id = group) %>% # duplicate group column and group by it
nest() %>% # nest data
left_join(look_up, by="group_id") %>% # join look up table to get corresponding breaks
mutate(d = map2(br, data, ~f(.x, .y))) # apply function
# see results
df_upd$d
# [[1]]
# ID date group val.(0,10] val.(10,30] val.(30,100]
# 1 A C G 0 5 1
# 2 A D G 1 4 1
# 3 B E G 1 3 2
# 4 B F G 1 5 0
#
# [[2]]
# ID date group val.(0,10] val.(10,50] val.(50,100]
# 1 A C H 0 6 0
# 2 B E H 1 3 0
# 3 B F H 0 5 0
我决定使用您提供的函数,它显然包括对列名的中断。因此,当您对不同的组有不同的中断时,输出不能包含在一个数据框中,因为会有列名冲突。
在一个数据框中获取所有内容的唯一方法是更改函数以产生更“整洁”的输出:
library(tidyverse)
# updated function
f = function(br, df) {
df %>%
mutate(g = cut(val, br)) %>%
na.omit() %>%
count(g, ID, date, group) %>%
complete(g, nesting(ID, date, group), fill=list(n=0)) }
# same lookup table
look_up = data_frame(group_id = c("G","H"),
br = list(c(0,10,30,100), c(0,10,50,100)))
# apply your function
df %>%
group_by(group_id = group) %>%
nest() %>%
left_join(look_up, by="group_id") %>%
mutate(d = map2(br, data, ~f(.x, .y))) %>%
unnest(d) %>%
select(-group_id) %>%
arrange(group, date, ID) # for visualisation purposes only
# # A tibble: 21 x 5
# g ID date group n
# <chr> <fct> <fct> <fct> <dbl>
# 1 (0,10] A C G 0
# 2 (10,30] A C G 5
# 3 (30,100] A C G 1
# 4 (0,10] A D G 1
# 5 (10,30] A D G 4
# 6 (30,100] A D G 1
# 7 (0,10] B E G 1
# 8 (10,30] B E G 3
# 9 (30,100] B E G 2
# 10 (0,10] B F G 1
# # ... with 11 more rows