在dplyr中,使用字符串向量输入可以按多个列进行分组。

11 浏览
0 Comments

在dplyr中,使用字符串向量输入可以按多个列进行分组。

我正在尝试将我对plyr的理解转换到dplyr中,但我无法弄清楚如何按多列进行分组。\n

# 使用无法硬编码的奇怪列名创建数据
data = data.frame(
  asihckhdoydkhxiydfgfTgdsx = sample(LETTERS[1:3], 100, replace=TRUE),
  a30mvxigxkghc5cdsvxvyv0ja = sample(LETTERS[1:3], 100, replace=TRUE),
  value = rnorm(100)
)
# 获取我们想要在其中求平均值的列
columns = names(data)[-3]
# plyr - 可行
ddply(data, columns, summarize, value=mean(value))
# dplyr - 报错
data %.%
  group_by(columns) %.%
  summarise(Value = mean(value))
#> Error in eval(expr, envir, enclos) : index out of bounds

\n我在将plyr示例转换为dplyr风格的语法时漏掉了什么?

0
0 Comments

在dplyr中,对多个列进行分组是相对较弱的支持,作者表示最终语法可能会是类似于df %.% group_by(.groups = c("asdfgfTgdsx", "asdfk30v0ja")),但可能需要一段时间来实现(因为需要考虑所有后果)。然而,在此期间,可以使用regroup()来实现,它接受一个符号列表作为参数。如果有一个字符向量的列名,可以使用lapply()as.symbol()将其转换成正确的结构。解决这个问题的关键是使用as.symbol函数。在dplyr 0.4.3之后,regroup已被弃用。

0
0 Comments

问题:在dplyr中如何按多个列进行分组?

问题的原因:在使用dplyr进行数据处理时,有时需要按多个列进行分组。然而,在早期的版本中,dplyr的group_by函数只能按单个列进行分组,无法满足用户的需求。

解决方法:为了解决这个问题,dplyr在后续的版本中添加了scoped版本的group_by函数。这个函数可以接受一个字符串向量作为输入,实现按多个列进行分组的功能。使用这个函数的方法如下:

data = data.frame(
    asihckhdoydkhxiydfgfTgdsx = sample(LETTERS[1:3], 100, replace=TRUE),
    a30mvxigxkghc5cdsvxvyv0ja = sample(LETTERS[1:3], 100, replace=TRUE),
    value = rnorm(100)
)
# get the columns we want to average within
columns = names(data)[-3]
library(dplyr)
df1 <- data %>%
  group_by_at(vars(one_of(columns))) %>%
  summarize(Value = mean(value))

这样就可以按columns中指定的多个列对data进行分组,并计算每组的value列的平均值。与此同时,为了验证结果的正确性,还可以使用plyr包中的ddply函数进行比较,代码如下:

df2 <- plyr::ddply(data, columns, plyr::summarize, value=mean(value))
table(df1 == df2, useNA = 'ifany')

可以看到,通过比较df1和df2的结果,可以发现它们是相同的。

需要注意的是,由于dplyr的summarize函数只能去掉一层分组,所以在df1的结果中仍然存在一层分组。为了完全去除这一层分组,可以在summarize后面加上%>% ungroup代码。

除了使用group_by_at函数,还可以使用group_by函数的.dots参数来实现按多个列进行分组,如下所示:

data %>% group_by(.dots = columns) %>% summarize(value = mean(value))

在这种方式下,使用.dots参数来指定要按哪些列进行分组。

另外,对于问题“如何在多个列上计算平均值”,可以使用select语法中的新函数across来实现。具体使用方法可以参考dplyr的官方文档(https://dplyr.tidyverse.org/reference/across.html)。例如,如果想要计算value_A和value_B列的平均值,可以使用下面的代码:

summarize(across(all_of(c('value_A', 'value_B')), mean))

通过这种方式,可以方便地在多个列上应用函数进行计算。

0
0 Comments

问题的出现原因是想要使用dplyr包中的group_by函数按照多个列进行分组,但是要求输入的分组列是一个字符串向量,而不是硬编码的列名。在给出的代码中,虽然使用了lapply函数将字符串向量转换为符号列表,但仍然需要在group_by函数中使用.dots参数来指定分组列。

解决方法是使用lapply函数将字符串向量转换为符号列表,并将该列表作为.dots参数传递给group_by函数。具体的实现代码如下:

library(dplyr)
df <-  data.frame(
    asihckhdoydk = sample(LETTERS[1:3], 100, replace=TRUE),
    a30mvxigxkgh = sample(LETTERS[1:3], 100, replace=TRUE),
    value = rnorm(100)
)
# Columns you want to group by
grp_cols <- names(df)[-3]
# Convert character vector to list of symbols
dots <- lapply(grp_cols, as.symbol)
# Perform frequency counts
df %>%
    group_by_(.dots=dots) %>%
    summarise(n = n())

运行上述代码后,可以得到按照两个列进行分组的结果。输出结果如下:

Source: local data frame [9 x 3]
Groups: asihckhdoydk
  asihckhdoydk a30mvxigxkgh  n
1            A            A 10
2            A            B 10
3            A            C 13
4            B            A 14
5            B            B 10
6            B            C 12
7            C            A  9
8            C            B 12
9            C            C 10

通过这种方法,可以实现按照字符串向量指定的多个列进行分组的功能。

0