【问题标题】:group_by() and summarise() by rowgroup_by() 和 summarise() 按行
【发布时间】:2022-11-15 01:02:13
【问题描述】:

我有一个数据,每次都有几个行 id 和 -infinite 值,我想使用 R 包 dplyr 和 tidyverse 来计算每次每个 ID 的 -infinite 平均数。

这是我的数据:

dt <- data.frame(id = rep(1:3, each = 4), 
                 time = rep(1:4, time=3), 
                 x = c(1, 2, 1, -Inf, 2, -Inf,1, 1, 5, 1, 2, 1), 
                 y = c(2, -Inf, -Inf, -Inf, -Inf, 5, -Inf, 2, 1, 2, 2, 2)) 

在实际数据中,我有 100 多列,但为了简化,我只放了 x 和 y。

预期结果:

  id time   n
2  1    2 0.5
3  1    3 0.5
4  1    4 1.0
5  2    1 0.5
6  2    2 0.5
7  2    3 0.5

这个想法是根据特定的计算函数使用一些特定的列来生成一个向量。 搜索后我找到了 rowwise() 函数,但它没有帮助,这是我的尝试:

dt %>%
  group_by(id,time) %>%
  summarise(n = across(x:y, ~mean(is.infinite(x) & x < 0, na.rm=TRUE)))

dt %>%
  group_by(id,time) %>% 
  rowwise() %>%
  summarise(n = across(everything(), ~mean(is.infinite(x) & x < 0, na.rm=TRUE)))

dt %>%
  rowwise() %>%
  summarise(n = across(everything(), ~mean(is.infinite(x) & x < 0, na.rm=TRUE)))
 
# same results:
`summarise()` has grouped output by 'id'. You can override using the `.groups` argument.
# A tibble: 12 x 3
# Groups:   id [3]
      id  time   n$x    $y
   <int> <int> <dbl> <dbl>
 1     1     1     0     0
 2     1     2     0     0
 3     1     3     0     0
 4     1     4     1     1
 5     2     1     0     0
 6     2     2     1     1
 7     2     3     0     0
 8     2     4     0     0
 9     3     1     0     0
10     3     2     0     0
11     3     3     0     0
12     3     4     0     0

你能帮我生成这个向量 n 吗?

【问题讨论】:

  • 我不确定您的数据是否可行。您的 12 行是 id 和时间的 12 个唯一组合。因此,对于每个子组,都有一个值,它要么是无限的(给 1),要么不是无限的(给 0)
  • 抱歉,我现在知道您的目标是什么 - x 和 y 是两个观察结果,您对两者进行平均?看看下面的代码是否有帮助。

标签: r dplyr tidyr rowwise


【解决方案1】:

这个解决方案怎么样?它看起来像是提供了所需的输出并且是可扩展的。
首先我“融化”列 x 和 y,然后总结 id 和 time:

dt %>% 
   reshape2::melt(id = c("id", "time")) %>% 
   group_by(id, time) %>% 
   summarise(count_neg_inf = mean(value == -Inf, na.rm = TRUE))

问候,
塞缪尔

【讨论】:

  • 感谢您的帮助,我使用了您的解决方案并稍作修改 summarise(count_neg_inf = mean(is.infinite(value) & value < 0, na.rm=TRUE)) %>% filter(count_neg_inf != 0)
【解决方案2】:

我想我更了解你在这里的目的是什么。 across 不需要(因为它更多地用于修改列)。 rowwise 或 group_by 都可以:

library(dplyr)

dt <- data.frame(id = rep(1:3, each = 4), 
                 time = rep(1:4, times = 3), 
                 x = c(1, 2, 1, -Inf, 2, -Inf,1, 1, 5, 1, 2, 1), 
                 y = c(2, -Inf, -Inf, -Inf, -Inf, 5, -Inf, 2, 1, 2, 2, 2)) 

dt %>% 
  group_by(id, time) %>% 
  summarise(n = mean(c(is.infinite(x), is.infinite(y)))) %>% 
  filter(n != 0)
#> `summarise()` has grouped output by 'id'. You can override using the `.groups`
#> argument.
#> # A tibble: 6 × 3
#> # Groups:   id [2]
#>      id  time     n
#>   <int> <int> <dbl>
#> 1     1     2   0.5
#> 2     1     3   0.5
#> 3     1     4   1  
#> 4     2     1   0.5
#> 5     2     2   0.5
#> 6     2     3   0.5

创建于 2022 年 11 月 14 日,reprex v2.0.2

【讨论】:

  • @AndryBaxter 我们能否改进代码以覆盖更多列(+100),在上面的示例中我只给出了两个颜色 x,y 来简化?
猜你喜欢
  • 2018-12-24
  • 2015-07-27
  • 2019-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-29
  • 1970-01-01
相关资源
最近更新 更多