使用示例可以最好地解释问题。
library(dplyr)
library(data.table)
df <- data.frame(
id = c(1,1,2,2),
x = 1:4
)
假设我们需要得到组的平均值,乘以组值。在
data.table
中,这工作起来简单直观。
> setDT(df)[, .(mean(x) * id), by=id]
id V1
1: 1 1.5
2: 2 7.0
但是,在
dplyr
中,存在警告和行重复。
> df |> group_by(id) |> summarise(mean(x) * id)
`summarise()` has grouped output by 'id'. You can override using the `.groups` argument.
# A tibble: 4 × 2
# Groups: id [2]
id `mean(x) * id`
<dbl> <dbl>
1 1 1.5
2 1 1.5
3 2 7
4 2 7
Warning message:
Returning more (or less) than 1 row per `summarise()` group was deprecated in dplyr 1.1.0.
ℹ Please use `reframe()` instead.
我意识到我可以通过添加额外的
unique()
步骤来消除重复,但不禁感觉 dplyr
在这种情况下没有得到应有的使用。
我们必须使用
cur_group_id()
。
library(dplyr)
df |>
summarise(v1 = mean(x) * cur_group_id(), .by = id)
id v1
1 1 1.5
2 2 7.0
这是预期的行为。正如您所注意到的,
mean(x)
始终是单个值,而id
是长度为n()
的向量(此处为2)。所以,你正在做的,例如在第一组中,1 * c(1.5, 1.5)
,它返回大小为 2 的向量。
使用任何类型的总结措施(例如
unique
或mean
)都可以解决该问题。
您可以使用
cur_group()
获取当前群组信息。然后从那里提取ID
df |> summarise(mean(x) * cur_group()$id, .by=id)
# id mean(x) * cur_group()$id
# 1 1 1.5
# 2 2 7.0