首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当组不是NA时的汇总统计信息

当组不是NA时的汇总统计信息
EN

Stack Overflow用户
提问于 2021-08-28 12:35:09
回答 3查看 145关注 0票数 1

我想计算第1组、第2组和第3组的重量和高度汇总统计数据(平均,范围)。我特别想通过计算当第1组不为NA (对于calc组1)时计算汇总统计量来实现这一点,而对于第2组,当列不是NA时,我想要通过计算汇总统计量来实现这一点。

在下面的例子中,第1组的权重为3,2,第2组的权重为3,5。

代码语言:javascript
复制
dt <- tibble(
  group1 = c(1, 1, NA, NA, NA, NA),
  group2 = c(NA, NA, 2, 2, NA, NA),
  group3 = c(NA, NA, NA, NA, 3, 3),
  weight = c(3, 2, 3, 5, NA, 7),
  height = c(10, NA, 14, 15, 11, 20)
)
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-08-28 13:23:13

你可以试试

代码语言:javascript
复制
library(dplyr)
library(tidyr)

dt %>% 
  group_by(group = coalesce(group1, group2, group3)) %>% 
  summarize(
    mean_weight = mean(weight, na.rm = TRUE),
    mean_height = mean(height, na.rm = TRUE)
    )

回传

代码语言:javascript
复制
# A tibble: 3 x 3
  group mean_weight mean_height
  <dbl>       <dbl>       <dbl>
1     1         2.5        10  
2     2         4          14.5
3     3         7          15.5

如果每一行有多个组,则可以使用

代码语言:javascript
复制
dt %>% 
  pivot_longer(
    starts_with("group"),
    values_drop_na = TRUE,
    values_to = "group"
    ) %>%
  group_by(group) %>% 
  summarize(
    mean_weight = mean(weight, na.rm = TRUE),
    mean_height = mean(height, na.rm = TRUE)
  )

它的返回基本相同。

代码语言:javascript
复制
# A tibble: 3 x 3
  group mean_weight mean_height
  <dbl>       <dbl>       <dbl>
1     1         2.5        10  
2     2         4          14.5
3     3         7          15.5

这是怎么回事?

  1. 首先我们使用pivot_longer将数据转换成“长”格式。我们以"group“(starts_with("group"))开头的每一列。这些列名进入新列name (默认名称,您可以用names_to = "YourNewColumnNameHere"更改它)。使用group将这些值放入新列values_to = "group"中。如果不使用此参数,则默认情况下值存储在列value中。values_drop_na = TRUE负责处理每个包含NA值的单元格。这些都被移除了。因此,在使用pivot_longer之后,转换后的数据看起来像

代码语言:javascript
复制
# A tibble: 6 x 4
  weight height name   group
   <dbl>  <dbl> <chr>  <dbl>
1      3     10 group1     1
2      2     NA group1     1
3      3     14 group2     2
4      5     15 group2     2
5     NA     11 group3     3
6      7     20 group3     3

因此,下一个转换将应用于每个独立的组,不影响每个other.

  • summarize,接受分组并计算每个组的新列。所有其他列都会被删除。na.rm = TRUE参数mean()负责处理NA值:这些值被忽略。如果没有这个参数,组NA.

mean_weight将是3

编辑

由于akrun注释,可以将其推广到多个列,而无需使用大爆炸运算符进行整形:

代码语言:javascript
复制
dt %>% 
  group_by(group = coalesce(!!! select(., starts_with('group')))) %>% 
  summarise(across(c(weight, height), mean, na.rm = TRUE))

akrun使用了一种更高级的方法:

statement.

  • coalesce()的核心是
  1. ,它是一个用于按照参数顺序获得第一个非NA-element的函数。例如:coalesce(NA_real_, 1, 2)返回1,因为这是第一个非NA-value。由于coalesce()是向量化的,所以coalesce(group1, group2, group3)和组列只包含一行

中的一个值。

代码语言:javascript
复制
dt %>% 
  group_by(group = coalesce(group1, group2, group3))

返回一个已经分组的tibble。

代码语言:javascript
复制
# A tibble: 6 x 6
# Groups:   group [3]
  group1 group2 group3 weight height group
   <dbl>  <dbl>  <dbl>  <dbl>  <dbl> <dbl>
1      1     NA     NA      3     10     1
2      1     NA     NA      2     NA     1
3     NA      2     NA      3     14     2
4     NA      2     NA      5     15     2
5     NA     NA      3     NA     11     3
6     NA     NA      3      7     20     3

如果有许多/多个列名为

  1. ,我们不想输入coalesce(group1, ... , group100)。所以我们使用一个函数,它选择所有的列。在这里,!!! select(., starts_with('group'))是最好的方法:将data.frame的每一列以"group“开头。不幸的是,select返回一个data.frame (这是向量列表的一个特殊版本)。我们需要为coalesce提供多个向量作为参数。向量列表无法完成任务:

代码语言:javascript
复制
dt %>% 
  group_by(group = coalesce(select(., starts_with('group')))) 

返回

代码语言:javascript
复制
# Groups:   group [3]
  group1 group2 group3 weight height group$group1 $group2 $group3
   <dbl>  <dbl>  <dbl>  <dbl>  <dbl>        <dbl>   <dbl>   <dbl>
1      1     NA     NA      3     10            1      NA      NA
2      1     NA     NA      2     NA            1      NA      NA
3     NA      2     NA      3     14           NA       2      NA
4     NA      2     NA      5     15           NA       2      NA
5     NA     NA      3     NA     11           NA      NA       3
6     NA     NA      3      7     20           NA      NA       3

这不是我们要找的。大爆炸算符!!!将这个向量列表分割成多个向量,这些向量作为参数提供给coalesce。所以

代码语言:javascript
复制
dt %>% 
  group_by(group = coalesce(!!! select(., starts_with('group')))) 

返回

代码语言:javascript
复制
# A tibble: 6 x 6
# Groups:   group [3]
  group1 group2 group3 weight height group
   <dbl>  <dbl>  <dbl>  <dbl>  <dbl> <dbl>
1      1     NA     NA      3     10     1
2      1     NA     NA      2     NA     1
3     NA      2     NA      3     14     2
4     NA      2     NA      5     15     2
5     NA     NA      3     NA     11     3
6     NA     NA      3      7     20     3

  1. ,所以现在我们有了一个分组Dataa.Frame/tibble,我们可以应用summarise函数:summarise(across(c(weight, height), mean, na.rm = TRUE))across()告诉summarise将带参数na.rm = TRUE的函数mean应用于列weightheight。这是

的一个更优雅的版本

代码语言:javascript
复制
summarize(
    mean_weight = mean(weight, na.rm = TRUE),
    mean_height = mean(height, na.rm = TRUE)
    )

如果没有重命名(这也可以用across完成)。

票数 2
EN

Stack Overflow用户

发布于 2021-08-28 19:08:08

带有data.table的选项

代码语言:javascript
复制
library(data.table)
setDT(dt)[, lapply(.SD, mean, na.rm = TRUE),
        .(group = fcoalesce(group1, group2, group3)),
        .SDcols = c('weight', 'height')]
   group weight height
1:     1    2.5   10.0
2:     2    4.0   14.5
3:     3    7.0   15.5
票数 2
EN

Stack Overflow用户

发布于 2021-08-28 12:46:16

您可以为每个组查找汇总统计信息,然后将NA过滤掉。以group1为例。

代码语言:javascript
复制
dt %>%
  group_by(group1) %>%
  summarise(mean_weight = mean(weight, na.rm=T),
            mean_height = mean(height, na.rm=T),
            .groups = 'drop') %>%
  filter(!(is.na(group1)))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68964417

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档