如何删除重复行并计算其频率?

时间:2013-04-28 06:12:57

标签: r

我有data.frame

ID  code
A    1
A    1
A    2
A    1
B    4
B    1
B    1
C    2
C    3
C    3
C    2

我知道如何删除,但我必须计算频率:

ID  code  freq
A    1     3
A    2     1
B    4     1
B    1     2
C    2     2
C    3     2

2 个答案:

答案 0 :(得分:2)

有几种方法。这是一个使用ave

的人
unique(within(mydf, {
  Freq <- ave(code, ID, code, FUN = length)
}))
#   ID code Freq
# 1  A    1    3
# 3  A    2    1
# 5  B    4    1
# 6  B    1    2
# 8  C    2    2
# 9  C    3    2

或者,另一个选项(但行顺序不同):

X <- data.frame(table(mydf))
X[X$Freq != 0, ]
#    ID code Freq
# 1   A    1    3
# 2   B    1    2
# 4   A    2    1
# 6   C    2    2
# 9   C    3    2
# 11  B    4    1

更新

如果您愿意使用套餐(此答案中的其他两个选项使用基数R),您应该查看&#34; data.table&#34;,特别是如果您的数据很大:

library(data.table)
DT <- data.table(mydf)
DT[, .N, by = c("ID", "code")]
#    ID code N
# 1:  A    1 3
# 2:  A    2 1
# 3:  B    4 1
# 4:  B    1 2
# 5:  C    2 2
# 6:  C    3 2

基准

以下是较大数据集的一些基准测试,以了解选项如何扩展。

library(microbenchmark)
library(data.table)

制作一些数据:

set.seed(1)
mydf <- data.frame(ID = sample(LETTERS, 100000, replace = TRUE), 
                   code = sample(1:10, 100000, replace = TRUE))
DT <- data.table(mydf)

建立你的职能:

AM1 <- function() {
  X <- data.frame(table(mydf))
  X[X$Freq != 0, ]
}

AM2 <- function() {
  unique(within(mydf, {
    Freq <- ave(code, ID, code, FUN = length)
  }))
}

AM3 <- function() {
  DT[, .N, by = c("ID", "code")]
}

DDP <- function() {
  ddply(mydf, .(ID, code), nrow)
}

基准:

microbenchmark(AM1(), AM2(), AM3(), DDP(), times=100)
# Unit: milliseconds
#   expr       min        lq    median        uq       max neval
# AM1()  65.64750  66.92666  68.86916  70.25277 137.12961   100
# AM2() 224.85660 228.05091 230.02311 232.77116 295.55184   100
# AM3()  11.15789  11.30541  11.44706  11.72064  77.72398   100
# DDP()  97.75484 100.86891 103.42602 106.85045 171.02863   100

在小型数据集上(您可以尝试一下),AM2()应该是最快的,但它不能很好地扩展,如上面的结果所示。但是,AM3()(&#34; data.table&#34;选项)对于较大的数据集来说很难。

答案 1 :(得分:2)

使用ddply包中的plyr

library(plyr)
dfDuplicates = as.data.frame(read.table(textConnection("ID  code
A    1
A    1
A    2
A    1
B    4
B    1
B    1
C    2
C    3
C    3
C    2"), header = TRUE))

ddply(dfDuplicates, .(ID, code), nrow)