【问题标题】:Count combinations of two variables excluding rows that repeat ID计算两个变量的组合,不包括重复 ID 的行
【发布时间】:2016-10-03 14:24:10
【问题描述】:

我有一个关于国家/地区的数据,想对其进行汇总并创建一个表格。

> head(data)
         country year score members
              A 1989     0       7
              A 1990     0       7
              A 1991     0       7
              A 1992     0       7
              A 1993     0       7
              A 1994     0       7

表格应该显示国家“分数”和“成员”数量之间的关系——换句话说,我想看看有多少分数为 0,1 或 2 的州有“成员”(范围从 1 到 7) .

我想这样设置:

score members==1 members==2 members==3 members==4 members==5 members==6 members==7
0        1          0
1        2          0
2        0          1  and so on..

为此,我运行以下命令:

library(dplyr)
    table <- data %>%
      group_by(score) %>% 
      summarise(
        m1    = sum(members==1, na.rm=TRUE),
        m2    = sum(members==2, na.rm=TRUE),
        m3    = sum(members==3, na.rm=TRUE),
        m4    = sum(members==4, na.rm=TRUE),
        m5    = sum(members==5, na.rm=TRUE),
        m6    = sum(members==6, na.rm=TRUE),
        m7    = sum(members==7, na.rm=TRUE)

      )

这给出:

    score    m1    m2    m3    m4    m5    m6    m7
        0     0     2     0     0     0     3    30
        1    15     3    11    11     3    18     3
        2     3     0     2     2     0     6     9
.
.

我需要一点帮助。如您所见,它计算了观察总数,而我只想计算每个国家/地区一次。

如何汇总这些数据以获得每个会员级别的国家总数?

以下是我的数据样本,用于重现性:

data <-
structure(list(country = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 5L, 
5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 
5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 
6L, 6L, 6L), .Label = c("A", "B", "C", "D", "E", "F"), class = "factor"), 
    year = c(1989L, 1990L, 1991L, 1992L, 1993L, 1994L, 1995L, 
    1996L, 1997L, 1998L, 1999L, 2000L, 2001L, 2002L, 2003L, 2004L, 
    2005L, 2006L, 2007L, 2008L, 2010L, 1989L, 1990L, 1991L, 1992L, 
    1993L, 1994L, 1995L, 1996L, 1997L, 1998L, 1999L, 2000L, 2001L, 
    2002L, 2003L, 2004L, 2005L, 2006L, 2007L, 2008L, 2009L, 2010L, 
    2011L, 1989L, 1991L, 1993L, 1994L, 1995L, 1996L, 1997L, 1999L, 
    2000L, 2001L, 2002L, 2003L, 2004L, 2005L, 2006L, 2007L, 2008L, 
    2010L, 1989L, 1990L, 1991L, 1992L, 1993L, 1994L, 1995L, 1996L, 
    1997L, 1998L, 1999L, 2000L, 2001L, 2002L, 2003L, 2004L, 2005L, 
    2006L, 2007L, 2008L, 2009L, 2010L, 2011L, 1991L, 1992L, 1993L, 
    1994L, 1995L, 1997L, 1998L, 1999L, 2000L, 2001L, 2002L, 2003L, 
    2004L, 2005L, 2006L, 2007L, 2008L, 2010L, 1991L, 1992L, 1993L, 
    1994L, 1995L, 1997L, 1998L, 1999L, 2000L, 2001L, 2002L, 2003L, 
    2004L, 2005L, 2006L, 2007L, 2008L, 2010L), score = c(0L, 
    0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
    0L, 0L, 0L, 0L, 0L, 1L, 0L, 1L, 1L, 0L, 1L, 1L, 0L, 1L, 1L, 
    1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 2L, 2L, 
    2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 
    2L, 0L, 1L, 1L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
    1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 2L, 2L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L
    ), members = c(7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 
    7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 6L, 6L, 6L, 6L, 6L, 
    6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 
    7L, 7L, 7L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 
    7L, 7L, 7L, 7L, 7L, 7L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 
    4L, 4L, 4L, 4L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
    4L, 4L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L)), .Names = c("country", "year", "score", 
"members"), class = "data.frame", row.names = c(NA, -121L))

【问题讨论】:

  • with(data, table(score, members))
  • with(data, table(score, members, country)),如果必须是每个国家/地区
  • 你想要的输出到底是什么?

标签: r database dplyr


【解决方案1】:

我相信你需要这个:

library(reshape2)
dcast(aggregate(country~score+members, data=data, FUN=function(x) length(unique(x))), 
      score~members, value.var="country", fill=0L)
#  score 1 2 3 4 5 6 7
#1     0 0 1 0 0 0 1 2
#2     1 1 1 2 2 1 3 2
#3     2 1 0 1 2 0 1 1

或者说dplyr/tidyr的方式:

data %>% 
     group_by(members, score) %>% 
     summarise(n=n_distinct(country)) %>% 
     spread(members, n, fill=0L)

## A tibble: 3 x 8
#  score     1     2     3     4     5     6     7
#* <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1     0     0     1     0     0     0     1     2
#2     1     1     1     2     2     1     3     2
#3     2     1     0     1     2     0     1     1

【讨论】:

  • @akrun 来吧,我们只是不以同样的方式理解 Q,我暗示了我认为 OP 想要的东西。除了现在,根据我的回答,我们没有得到相同的输出,您可以选择获取其他输出...
  • 我认为最好发布n_distinct(country),因为它是 dplyr 方式。我会删除我的。我想在下面发布您对我的回答的评论
【解决方案2】:

由于 OP 正在使用 dplyr 方法,我们可以通过与“分数”、“成员”分组来获取元素数量(n()),然后是 spread(来自 tidyr)将其重塑为“宽”格式。

library(dplyr)
library(tidyr)
data %>%
    group_by(score, members) %>%
    summarise(n = n()) %>%
    mutate(members = paste0("m", members)) %>%
    spread(members, n, fill = 0)
#  score    m1    m2    m3    m4    m5    m6    m7
#  <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1     0     0     2     0     0     0     3    30
#2     1    15     3    11    11     3    18     3
#3     2     3     0     2     2     0     6     9

如果我们还需要按“国家”获取计数,只需在group_by 中添加“国家”

data %>%
    group_by(country, score, members) %>%
    summarise(n = n()) %>%
    mutate(members = paste0("m", members)) %>%
    spread(members, n, fill = 0)

如果预期输出是其他帖子中显示的输出,则使用data.table 的选项是将'data.frame' 转换为'data.table' (setDT(data),并将dcast 从' long' 到 'wide' 将 fun.aggregate 指定为 'value.var' 变量的 uniqueN 即 'country',其中 uniqueN 返回 'country' 列中的 unique 元素的 lengthfill=0 指定为那些不可用的组合占用 0。默认情况下,它返回为 NA。

library(data.table)
dcast(setDT(data), score~members, value.var= 'country', fun.aggregate = uniqueN, fill = 0)   
#   score 1 2 3 4 5 6 7
#1:     0 0 1 0 0 0 1 2
#2:     1 1 1 2 2 1 3 2
#3:     2 1 0 1 2 0 1 1

【讨论】:

  • 这就是 OP 得到但不想得到的输出......:如您所见,它计算了观察总数而不是每个国家/地区
  • 是的(我真的看到了 2 个包和很多行来获得相同的 btw 的意义)但是,根据 OP 的评论,我认为这不是他们想要的
  • group_by(score, members) %&gt;% summarise(n = n())可以写成count(score, members)
【解决方案3】:

似乎问题的症结在于每年都有重复的行?在这种情况下,您可以使用distinct 删除它们,那么它就是一个简单的交叉表。您可以使用 magrittr 的 %$% exposition 管道:

library(dplyr)
library(magrittr)
data %>%
  distinct(country, score, members) %$%
  table(score, members)

     members
score 1 2 3 4 5 6 7
    0 0 1 0 0 0 1 2
    1 1 1 2 2 1 3 2
    2 1 0 1 2 0 1 1

或者一个普通的管道和来自管理员包的tabyl

library(dplyr)
library(janitor)
data %>%
  distinct(country, score, members) %>%
  tabyl(score, members)

 score 1 2 3 4 5 6 7
     0 0 1 0 0 0 1 2
     1 1 1 2 2 1 3 2
     2 1 0 1 2 0 1 1

【讨论】:

    猜你喜欢
    • 2015-09-20
    • 1970-01-01
    • 1970-01-01
    • 2015-01-12
    • 1970-01-01
    • 2022-10-13
    • 2018-12-13
    • 2012-01-01
    • 1970-01-01
    相关资源
    最近更新 更多