首页 > 解决方案 > 如何在 group_by (dplyr) 中使用 paste?

问题描述

我有以下数据(示例):

id <- c(1, 1, 2, 2, 2)
x <- c(2, 2, 3, 3, 4)
dat <- data.frame(id, x)

现在我可以按组(id)计算 x 的出现并保存在 dat2 中:

dat2 <- dat %>% group_by(id, x) %>% dplyr::mutate(count = n())

现在计算 id 的案例:

dat2 <- dat2 %>% group_by(id) %>% dplyr::mutate(j = n())

这一切正常。结果:

dat2

# A tibble: 5 x 4
# Groups:   id [2]
     id     x count     j
  <dbl> <dbl> <int> <int>
1     1     2     2     2
2     1     2     2     2
3     2     3     2     3
4     2     3     2     3
5     2     4     1     3

现在到我的问题。我想在“group_by”中使用粘贴。更准确地说,我想使用两个字符“占位符”i(用于 id)和 z(用于 x)来控制分组。我不想使用“真实”对象 id 和 x:

i <- "id"
z <- "x"

dat2 <- dat %>% group_by(dat[[paste(i, sep = "")]], dat[[paste(z, sep = "")]]) %>% dplyr::mutate(count = n())

这第一步也有效,与上述相同。但是,进入下一个最后一步时,会发生错误:

dat2 <- dat2 %>% group_by(dat[[paste(i, sep = "")]]) %>% dplyr::mutate(j = n ())

Error: Problem with `mutate()` input `..1`.
x Input `..1` can't be recycled to size 2.
i Input `..1` is `dat[[paste(i, sep = "")]]`.
i Input `..1` must be size 2 or 1, not 5.
i The error occured in group 1: dat[[paste(i, sep = "")]] = 1, dat[[paste(z, sep = "")]] = 2.
Run `rlang::last_error()` to see where the error occurred.

我的问题:如何在不使用粘贴的情况下避免此错误并获得与以前相同的结果?使用粘贴命令可能看起来很奇怪,但我需要使用字符占位符。

我很高兴有任何帮助!

标签: rdplyr

解决方案


我们可以使用across而不是paste

library(dplyr)
dat %>%
      group_by(across(all_of(c(i, z)))) %>% 
      mutate(count = n()) %>%
      group_by(across(all_of(i))) %>% 
      mutate(j = n())
# A tibble: 5 x 4
# Groups:   id [2]
     id     x count     j
  <dbl> <dbl> <int> <int>
1     1     2     2     2
2     1     2     2     2
3     2     3     2     3
4     2     3     2     3
5     2     4     1     3

或者代替分组,使用add_count

dat %>% 
   add_count(across(all_of(c(i, z))), name = 'count') %>% 
   add_count(across(all_of(i)), name = 'j')
  id x count j
1  1 2     2 2
2  1 2     2 2
3  2 3     2 3
4  2 3     2 3
5  2 4     1 3

推荐阅读