【问题标题】:R - group_by n_distinct for summariseR - group_by n_distinct 用于汇总
【发布时间】:2015-06-26 15:27:53
【问题描述】:

我的数据集是这样的

library(dyplr) 

dta = rbind(c(1,'F', 0), 
  c(1,'F', 0), 
  c(1,'F', 0), 
  c(2,'F', 1), 
  c(2,'F', 1), 
  c(3,'F', 1), 
  c(3,'F', 1), 
  c(3,'F', 1), 
  c(4,'M', 1), 
  c(4,'M', 1), 
  c(5,'M', 1), 
  c(6,'M', 0)
)

colnames(dta) <- c('id', 'sex', 'child')
dta = as.data.frame(dta)

所以数据是长格式的,以 id 作为个人标识符。

我的问题是,例如,当我尝试计算 sex 时, 由于 id 的重复,我没有正确的计数。

所以有 3 位女性和 3 位男性。

但是当我数数时我有

dta %>% 
  group_by(sex) %>% 
  summarise(n())

8 和 4 - 因为它计算的是行数而不是唯一的 id

交叉表也有同样的问题

dta %>% 
  group_by(sex, child) %>% 
  summarise(n())

如何在计数中指明唯一标识符 (n_distinct)?

【问题讨论】:

  • 您不想以这种方式创建数据集。 c(1,"F",0) 是一个字符向量。
  • @Frank,你是对的,我原来的数据集真的很难dput,我只是想创建一个简单的例子。

标签: r unique dplyr


【解决方案1】:

有很多不同的方法可以做到这一点,这里有一个:

dta %>% distinct(id) %>%
        group_by(sex) %>%
        summarise(n())

编辑:经过一些讨论,让我们测试一下快速变化方法的工作原理。

首先,一些更大的数据:

dta <- data.frame(id = rep(1:500, 30),
                  sex = rep (c("M", "F"), 750),
                  child = rep(c(1, 0, 0, 1), 375))

现在让我们运行不同的方法:

library(microbenchmark)

microbenchmark(
    distinctcount = dta %>% distinct(id) %>% count(sex),
    uniquecount = dta %>% unique %>% count(sex),
    distinctsummarise = dta %>% distinct(id) %>% group_by(sex) %>% summarise(n()),
    uniquesummarise = dta %>% unique %>% group_by(sex) %>% summarise(n()),
    distincttally= dta %>% distinct(id) %>% group_by(sex) %>% tally
)

在我的机器上:

Unit: milliseconds
              expr       min        lq      mean    median        uq       max neval
     distinctcount  1.576307  1.602803  1.664385  1.630643  1.670195  2.233710   100
       uniquecount 32.391659 32.885479 33.194082 33.072485 33.244516 35.734735   100
 distinctsummarise  1.724914  1.760817  1.815123  1.792114  1.830513  2.178798   100
   uniquesummarise 32.757609 33.080933 33.490001 33.253155 33.463010 39.937194   100
     distincttally  1.618547  1.656947  1.715741  1.685554  1.731058  2.383084   100

我们可以看到独特的作品在更大的数据上效果很差,所以最快的是:

dta %>% distinct(id) %>% count(sex)

【讨论】:

  • dplyr 的文档说distinct 只是unique 的更快(用C++ 编写)版本。事实上,我认为他们从事同样的工作。
  • @jeremycg 非常感谢! ... 除了速度之外,哪种解决方案最美观美丽? ;)
  • 我认为我的第一个是最好看的,因为我认为按照这个顺序,它更明确。如果你的想法不同,也许你喜欢其他人。
【解决方案2】:

基础包:

aggregate(id ~ sex, dta, function(x) length(unique(x))) 

输出:

  sex id
1   F  3
2   M  3

dplyr 的另一种选择:

library(dplyr) 
count_(unique(dta), vars = "sex") 

输出:

Source: local data frame [2 x 2]

  sex n
1   F 3
2   M 3

使用sqldf

library(sqldf)
sqldf("SELECT sex, COUNT(DISTINCT(id)) AS n 
      FROM dta GROUP BY sex")

输出:

  sex n
1   F 3
2   M 3

【讨论】:

    猜你喜欢
    • 2022-01-10
    • 2022-01-12
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    • 2021-01-19
    • 2023-01-13
    • 2020-05-26
    • 1970-01-01
    相关资源
    最近更新 更多