在 R dplyr 包中向 summarize_at 添加额外变量
Adding extra variables to summarize_at in the R dplyr package
我正在使用 R 的 dplyr
包来获取几个变量的汇总统计信息,其中许多变量的名称都相似。例如,我有数百个变量都命名为 doctor_id_X
,其中 X
是某个整数(例如 doctor_id_1
、doctor_id_33
、doctor_id_543
等) .我能够轻松获得这些“doctor_id
”变量的最大值,按 treatment1
分组,在 summarize_at
语句中使用所谓的 "helpers",如下所示:
mydf %>% group_by(treatment1) %>%
summarize_at(vars(contains("doctor_id")), max)
但是,除了获得这些 max
统计数据之外,我还试图获得一些其他变量的平均值,这些变量的名称与 doctor_id
变量之一不同,称之为 procedure_time
。有没有办法通过修改上面的代码来有效地做到这一点?
为了更好地解释我正在尝试做的事情,这里有一个数据框的玩具示例:
library(dplyr)
set.seed(20190813)
mydf <- data.frame(treatment1 = sample(LETTERS[1:3], 100, replace=TRUE),
treatment2 = sample(LETTERS[4:5], 100, replace=TRUE),
doctor_id_1=rbinom(100, 1, .01),
doctor_id_2=rbinom(100, 1, .5),
doctor_id_3=rbinom(100, 1, .6),
doctor_id_4=rbinom(100, 1, .7),
y=rnorm(100))
head(mydf)
treatment1 treatment2 doctor_id_1 doctor_id_2 doctor_id_3 doctor_id_4 y
1 A D 0 0 1 0 -1.1175362
2 A E 0 0 1 1 -2.2813598
3 A D 0 1 1 0 0.5886914
4 A D 0 0 1 1 0.9854405
5 B E 0 0 1 1 1.8831306
6 A E 0 1 1 1 -0.3875261
通过 doctor_id
变量获取 max
值摘要没有问题:
mydf %>% group_by(treatment1) %>%
summarize_at(vars(contains("doctor_id")), max)
# A tibble: 3 x 5
treatment1 doctor_id_1 doctor_id_2 doctor_id_3 doctor_id_4
<fct> <int> <int> <int> <int>
1 A 1 1 1 1
2 B 0 1 1 1
3 C 0 1 1 1
但是现在,我还想在我的总结语句中找到 y
的 mean
。我试过了,但没用:
mydf %>% group_by(treatment1) %>%
summarize_at(y_avg=mean(y), vars(y, contains("doctor_id")), max)
但是,我确实注意到,下面的内容让我更接近我想要的,只是它为所有 doctor_id
变量和 y
变量生成了 max
,但我只需要 mean
作为 y
变量。
mydf %>% group_by(treatment1) %>%
summarize_at(vars(y, contains("doctor_id")), max)
# A tibble: 3 x 6
treatment1 y doctor_id_1 doctor_id_2 doctor_id_3 doctor_id_4
<fct> <dbl> <int> <int> <int> <int>
1 A 1.70 1 1 1 1
2 B 1.88 0 1 1 1
3 C 1.45 0 1 1 1
这也让我很接近,但它会为两个变量生成两个统计数据:
mydf %>% group_by(treatment1) %>%
summarize_at(vars(y, contains("doctor_id")), c(max, mean))
所以,总而言之,我的问题是,有没有什么方法可以在 summarize_by 语句中使用辅助函数,并且还包括另一个变量的不同统计信息,而不必求助于加入?
这是一个选项,我们可以使用 mutate
(然后也将其添加到 group_by
)或直接在 group_by
之后创建一个变量 'y_avg' 'treatment' 分组数据,然后执行 summarise_at
library(dplyr)
mydf %>%
group_by(treatment1) %>%
group_by(y_avg = mean(y), add = TRUE ) %>%
summarize_at(vars(contains("doctor_id")), max)
# A tibble: 3 x 6
# Groups: treatment1 [3]
# treatment1 y_avg doctor_id_1 doctor_id_2 doctor_id_3 doctor_id_4
# <fct> <dbl> <int> <int> <int> <int>
#1 A -0.216 0 1 1 1
#2 B 0.0659 0 1 1 1
#3 C -0.00830 1 1 1 1
或者另一种选择是在 mutate
中创建 'y_avg' 然后在 group_by
中使用它
mydf %>%
group_by(treatment1) %>%
mutate(y_avg = mean(y) %>%
group_by(y_avg, add = TRUE) %>%
summarize_at(vars(contains("doctor_id")), max)
或者另一种选择是 select
只有感兴趣的变量,在按 'treatment' 分组后使用 mutate
和 mutate_at
更新列,然后 [=数据集的 23=] 行
mydf %>%
select(treatment1, y_avg = y, contains('doctor_id')) %>%
group_by(treatment1) %>%
mutate(y_avg = mean(y_avg)) %>%
mutate_at(vars(contains('doctor_id')), max) %>%
distinct
或带有 data.table
的选项
library(data.table)
setDT(mydf)[, c(.(y_avg = mean(y)), lapply(.SD, max)),
.(treatment1), .SDcols = grep('doctor_id', names(mydf))]
#. treatment1 y_avg doctor_id_1 doctor_id_2 doctor_id_3 doctor_id_4
#1: C -0.008299684 1 1 1 1
#2: B 0.065875911 0 1 1 1
#3: A -0.216200359 0 1 1 1
我们可以 group_by
treatment
使用 mutate
计算 y
的 mean
,在 summarise_at
中添加该列以获得 max
所有列。
library(dplyr)
mydf %>%
group_by(treatment1) %>%
mutate(y_avg = mean(y)) %>%
summarise_at(vars(y_avg, contains("doctor_id")), max)
# A tibble: 3 x 6
# treatment1 y_avg doctor_id_1 doctor_id_2 doctor_id_3 doctor_id_4
# <fct> <dbl> <int> <int> <int> <int>
#1 A -0.192 1 1 1 1
#2 B -0.0390 0 1 1 1
#3 C -0.165 0 1 1 1
我正在使用 R 的 dplyr
包来获取几个变量的汇总统计信息,其中许多变量的名称都相似。例如,我有数百个变量都命名为 doctor_id_X
,其中 X
是某个整数(例如 doctor_id_1
、doctor_id_33
、doctor_id_543
等) .我能够轻松获得这些“doctor_id
”变量的最大值,按 treatment1
分组,在 summarize_at
语句中使用所谓的 "helpers",如下所示:
mydf %>% group_by(treatment1) %>%
summarize_at(vars(contains("doctor_id")), max)
但是,除了获得这些 max
统计数据之外,我还试图获得一些其他变量的平均值,这些变量的名称与 doctor_id
变量之一不同,称之为 procedure_time
。有没有办法通过修改上面的代码来有效地做到这一点?
为了更好地解释我正在尝试做的事情,这里有一个数据框的玩具示例:
library(dplyr)
set.seed(20190813)
mydf <- data.frame(treatment1 = sample(LETTERS[1:3], 100, replace=TRUE),
treatment2 = sample(LETTERS[4:5], 100, replace=TRUE),
doctor_id_1=rbinom(100, 1, .01),
doctor_id_2=rbinom(100, 1, .5),
doctor_id_3=rbinom(100, 1, .6),
doctor_id_4=rbinom(100, 1, .7),
y=rnorm(100))
head(mydf)
treatment1 treatment2 doctor_id_1 doctor_id_2 doctor_id_3 doctor_id_4 y
1 A D 0 0 1 0 -1.1175362
2 A E 0 0 1 1 -2.2813598
3 A D 0 1 1 0 0.5886914
4 A D 0 0 1 1 0.9854405
5 B E 0 0 1 1 1.8831306
6 A E 0 1 1 1 -0.3875261
通过 doctor_id
变量获取 max
值摘要没有问题:
mydf %>% group_by(treatment1) %>%
summarize_at(vars(contains("doctor_id")), max)
# A tibble: 3 x 5
treatment1 doctor_id_1 doctor_id_2 doctor_id_3 doctor_id_4
<fct> <int> <int> <int> <int>
1 A 1 1 1 1
2 B 0 1 1 1
3 C 0 1 1 1
但是现在,我还想在我的总结语句中找到 y
的 mean
。我试过了,但没用:
mydf %>% group_by(treatment1) %>%
summarize_at(y_avg=mean(y), vars(y, contains("doctor_id")), max)
但是,我确实注意到,下面的内容让我更接近我想要的,只是它为所有 doctor_id
变量和 y
变量生成了 max
,但我只需要 mean
作为 y
变量。
mydf %>% group_by(treatment1) %>%
summarize_at(vars(y, contains("doctor_id")), max)
# A tibble: 3 x 6
treatment1 y doctor_id_1 doctor_id_2 doctor_id_3 doctor_id_4
<fct> <dbl> <int> <int> <int> <int>
1 A 1.70 1 1 1 1
2 B 1.88 0 1 1 1
3 C 1.45 0 1 1 1
这也让我很接近,但它会为两个变量生成两个统计数据:
mydf %>% group_by(treatment1) %>%
summarize_at(vars(y, contains("doctor_id")), c(max, mean))
所以,总而言之,我的问题是,有没有什么方法可以在 summarize_by 语句中使用辅助函数,并且还包括另一个变量的不同统计信息,而不必求助于加入?
这是一个选项,我们可以使用 mutate
(然后也将其添加到 group_by
)或直接在 group_by
之后创建一个变量 'y_avg' 'treatment' 分组数据,然后执行 summarise_at
library(dplyr)
mydf %>%
group_by(treatment1) %>%
group_by(y_avg = mean(y), add = TRUE ) %>%
summarize_at(vars(contains("doctor_id")), max)
# A tibble: 3 x 6
# Groups: treatment1 [3]
# treatment1 y_avg doctor_id_1 doctor_id_2 doctor_id_3 doctor_id_4
# <fct> <dbl> <int> <int> <int> <int>
#1 A -0.216 0 1 1 1
#2 B 0.0659 0 1 1 1
#3 C -0.00830 1 1 1 1
或者另一种选择是在 mutate
中创建 'y_avg' 然后在 group_by
mydf %>%
group_by(treatment1) %>%
mutate(y_avg = mean(y) %>%
group_by(y_avg, add = TRUE) %>%
summarize_at(vars(contains("doctor_id")), max)
或者另一种选择是 select
只有感兴趣的变量,在按 'treatment' 分组后使用 mutate
和 mutate_at
更新列,然后 [=数据集的 23=] 行
mydf %>%
select(treatment1, y_avg = y, contains('doctor_id')) %>%
group_by(treatment1) %>%
mutate(y_avg = mean(y_avg)) %>%
mutate_at(vars(contains('doctor_id')), max) %>%
distinct
或带有 data.table
library(data.table)
setDT(mydf)[, c(.(y_avg = mean(y)), lapply(.SD, max)),
.(treatment1), .SDcols = grep('doctor_id', names(mydf))]
#. treatment1 y_avg doctor_id_1 doctor_id_2 doctor_id_3 doctor_id_4
#1: C -0.008299684 1 1 1 1
#2: B 0.065875911 0 1 1 1
#3: A -0.216200359 0 1 1 1
我们可以 group_by
treatment
使用 mutate
计算 y
的 mean
,在 summarise_at
中添加该列以获得 max
所有列。
library(dplyr)
mydf %>%
group_by(treatment1) %>%
mutate(y_avg = mean(y)) %>%
summarise_at(vars(y_avg, contains("doctor_id")), max)
# A tibble: 3 x 6
# treatment1 y_avg doctor_id_1 doctor_id_2 doctor_id_3 doctor_id_4
# <fct> <dbl> <int> <int> <int> <int>
#1 A -0.192 1 1 1 1
#2 B -0.0390 0 1 1 1
#3 C -0.165 0 1 1 1