【问题标题】:summarizing counts of a factor with dplyr用 dplyr 汇总一个因子的计数
【发布时间】:2014-11-06 20:06:03
【问题描述】:

我想按列(所有者)对数据框进行分组,并输出一个新的数据框,该数据框在每次观察时对每种类型的因子进行计数。真实的数据框比较大,有10个不同的因素。

这是一些示例输入:

library(dplyr)
df = tbl_df(data.frame(owner=c(0,0,1,1), obs1=c("quiet", "loud", "quiet", "loud"), obs2=c("loud", "loud", "quiet", "quiet")))

  owner  obs1  obs2
1     0 quiet  loud
2     0  loud  loud
3     1 quiet quiet
4     1  loud quiet

我正在寻找如下所示的输出:

out = data.frame(owner=c("0", "0", "1", "1"), observation=c("obs1", "obs2", "obs1", "obs2"), quiet=c(1, 0, 1, 2), loud=c(1, 2, 1, 0))

  owner observation quiet loud
1     0        obs1     1    1
2     0        obs2     0    2
3     1        obs1     1    1
4     1        obs2     2    0

融化让我走到了一半:

melted = tbl_df(melt(df, id=c("owner")))

  owner variable value
1     0     obs1 quiet
2     0     obs1  loud
3     1     obs1 quiet
4     1     obs1  loud
5     0     obs2  loud
6     0     obs2  loud
7     1     obs2 quiet
8     1     obs2 quiet

但是最后一步是什么?如果 'value' 是一个数字,我会去:

melted %>% group_by(owner, variable) %>% summarise(counts=sum(value))

非常感谢!

【问题讨论】:

  • 这是一个老问题,但值得一提的是,dcast 有一个鲜为人知的功能,它允许您在这些情况下应用聚合/汇总功能。我认为它默认为计数。

标签: r dplyr


【解决方案1】:

2017 年的答案是

library(dplyr)
library(tidyr)

gather(df, key, value, -owner) %>%
  group_by(owner, key, value) %>%
  tally %>% 
  spread(value, n, fill = 0)

提供输出

Source: local data frame [4 x 4]
Groups: owner, key [4]

  owner   key  loud quiet
* <dbl> <chr> <dbl> <dbl>
1     0  obs1     1     1
2     0  obs2     2     0
3     1  obs1     1     1
4     1  obs2     0     2

2019 年的答案是:

gather(df, key, value, -owner) %>% 
    count(owner, key, value) %>% 
    spread(value, n, fill = 0)

【讨论】:

  • 这是最近更好的答案。
  • 2019 年的答案是 ````gather(df, key, value, -owner) %>% count(owner, key, value) %>% spread(value, n, fill = 0) ````
  • 在 2019 年是否推荐使用 pivot_longer/更宽于收集/传播?
【解决方案2】:

您可以将tidyrdplyr 一起使用

library(dplyr)
library(tidyr)

 df %>%
 gather(observation, Val, obs1:obs2) %>% 
 group_by(owner,observation, Val) %>% 
 summarise(n= n()) %>%
 ungroup() %>%
 spread(Val, n, fill=0)

给出输出

  #    owner observation loud quiet
  #1     0        obs1    1     1
  #2     0        obs2    2     0
  #3     1        obs1    1     1
  #4     1        obs2    0     2

【讨论】:

  • df %&gt;% gather(observation, Val, obs1:obs2) %&gt;% group_by(owner, variable, value) %&gt;% summarise(n= n()) %&gt;% spread(value, n, fill=0)
  • @Rory Kirchner 列名应该一致。在这里,在gather(...) 中,您创建了一个变量Val,但在group_by(...) 及以后的版本中,该变量被丢弃并在其位置使用了value
  • Hm-- Val -> 我的值:df %>% gather(observation, Val, obs1:obs2) -> 所有者变量值作为列名
  • 我的 spread 方法出现“索引越界”错误。
  • @Paulo Cardoso 它确实适用于我之前的版本。现在,您似乎必须在 spread 之前执行 ungroup(),因为 Val` 是 grouping 变量之一。
【解决方案3】:

如果你想放弃dplyr,你可以拆分成列表。

df <- split(df, list(df[[obs1]], df[[obs2]])

如果您想要count,您只需创建一个sapplylapply 调用来遍历列表并获取每个列表的计数。或者你想要的任何其他功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-09-18
    • 2021-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-23
    • 2021-11-10
    相关资源
    最近更新 更多