过去,当我需要在部分基于"group_by"汇总统计的R数据帧中创建一个新变量时,我总是使用以下顺序:
(1( 使用group_by((和summary((从基本(未分组(数据帧中的数据计算"组统计数据">
(2( 将基础数据帧与上一步的结果连接起来,然后使用mutate计算新的变量值。
然而,(在使用dplyr多年后!(我不小心在一个突变步骤中进行了"总结",一切似乎都正常。下面的代码片段中的选项#2对此进行了说明。我假设选项#2是可以的,因为我使用这两个选项得到了相同的结果,而且我今天在网上搜索到了类似的例子。然而,我不确定。
选项#2是可接受的做法,还是选项#1更可取(如果是,为什么(?
set.seed(123)
df <- tibble(year_ = c(rep(c(2019), 4), rep(c(2020), 4)),
qtr_ = c(rep(c(1,2,3,4), 2)),
foo = sample(seq(1:8)))
# Option 1: calc statistics then rejoin with input data
df_stats <- df %>%
group_by(year_) %>%
summarize(mean_foo = mean(foo))
df_with_stats <- left_join(df, df_stats) %>%
mutate(dfoo = foo - mean_foo)
# Option 2: everything in one go
df_with_stats2 <- df %>%
group_by(year_) %>%
mutate(mean_foo = mean(foo),
dfoo = foo - mean_foo)
df_with_stats
# A tibble: 8 x 5
year_ qtr_ foo mean_foo dfoo
<dbl> <dbl> <int> <dbl> <dbl>
1 2019 1 7 6 1
2 2019 2 8 6 2
3 2019 3 3 6 -3
4 2019 4 6 6 0
5 2020 1 2 3 -1
6 2020 2 4 3 1
7 2020 3 5 3 2
8 2020 4 1 3 -2
df_with_stats2
# A tibble: 8 x 5
# Groups: year_ [2]
year_ qtr_ foo mean_foo dfoo
<dbl> <dbl> <int> <dbl> <dbl>
1 2019 1 7 6 1
2 2019 2 8 6 2
3 2019 3 3 6 -3
4 2019 4 6 6 0
5 2020 1 2 3 -1
6 2020 2 4 3 1
7 2020 3 5 3 2
8 2020 4 1 3 -2
如果您无论如何都不需要中间对象,并且您甚至不需要在mutate语句中创建mean_foo
,那么选项2是可以的:
df %>% group_by(year_) %>% mutate(dfoo=foo-mean(foo))
还有数据表
setDT(df)[,dfoo:=foo-mean(foo), by =year_]