在按计数聚合之前折叠列

时间:2014-11-02 15:45:08

标签: r aggregate plyr

我所拥有的是一个非常简单的问题,但在大量的电路板搜索/阅读教程之后,我根本想不通。

我在第5列到第12列中有一个名称条目的df,它们都是一种类型。它们是名称字符串(例如,见下文)。我想要做的就是使用aggregate或ddply(或另一个,如果更容易......)函数来折叠这些列,然后返回每个唯一条目的计数。

ID | Name 1 | Name 2 | Name 3 
Row 1: 278 | John | Tim | Mike
Row 2: 279 | Tim | Steve | John
Row 3: 280 | Tim | Doug | Dave 

理想情况下,我会得到:

 Tim | 3 
 John | 2
 Mike | 1 
 etc. | 1 

我知道这对于一列是如何工作的:

counts=aggregate(numeric(nrow(df)), df[c(4)], length)

但是当我对多列使用类似的行时,它会返回七列的唯一组合,而不是带有聚合唯一条目和总和的nx2向量。

counts2=aggregate(numeric(nrow(df)),df[c(5:12)],FUN = function(x) length(unique(x)))

非常感谢你的帮助。

3 个答案:

答案 0 :(得分:3)

以下是使用dplyrtidyr

的一种方法
foo <- data.frame(id = 278:280,
                  Name1 = c("John", "Tim", "Mike"),
                  Name2 = c("Tim", "Steve", "John"),
                  Name3 = c("Tim", "Doug", "Dave"),
                  stringsAsFactors = FALSE)
library(dplyr)
library(tidyr)

foo %>%
    gather(var, names, -id) %>%
    count(names)

#  names n
#1  Dave 1
#2  Doug 1
#3  John 2
#4  Mike 1
#5 Steve 1
#6   Tim 3

答案 1 :(得分:2)

我并不像Hadley提出的软件包那样快速,但这就是我使用reshape2软件包解决问题的方法。这个想法(与上面相同)是将列折叠成一列,然后汇总该数据:

library(reshape2)

dcast(data = melt(foo, id.vars = "id"), value ~ .)
#---
  value .
1  Dave 1
2  Doug 1
3  John 2
4  Mike 1
5 Steve 1
6   Tim 3

答案 2 :(得分:1)

阅读您的数据:

txt <- "ID | Name 1 | Name 2 | Name 3 
Row 1: 278 | John | Tim | Mike
Row 2: 279 | Tim | Steve | John
Row 3: 280 | Tim | Doug | Dave "
dat <- read.csv(text = txt, sep = "|", strip.white = TRUE)

您可以在未列出的列上使用as.data.frame表方法。

u <- unlist(dat[-1])
as.data.frame(table(levels(u)[u]))
#    Var1 Freq
# 1  Dave    1
# 2  Doug    1
# 3  John    2
# 4  Mike    1
# 5 Steve    1
# 6   Tim    3