按组分组,计算唯一值数量并进行汇总。

3

我的数据集看起来像这样

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作为个人标识符。

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

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

但是当我计数时,我有:

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

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

跨表也有同样的问题

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

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


1
你不想以那种方式创建数据集。c(1,"F",0)是一个字符向量。 - Frank
1
@Frank,当然你是正确的,我的原始数据集非常难以进行'dput'处理,我只是想创建一个简单的示例。 - giac
2个回答

3

有许多不同的方法来实现这个,这里提供一种:

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)

1
dplyr 的文档说 distinct 只是 unique 的更快(用 C++ 编写)版本。实际上,我认为它们做的工作是一样的。 - SabDeM
@jeremycg 非常感谢!除了速度之外,哪个解决方案是最美观的呢?;) - giac
我认为我的初始版本是最好看的,因为我按照那个顺序思考,而且更加明确。如果你有不同的想法,也许你会喜欢其他版本。 - 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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接