与条件匹配的聚合(计数)行,按唯一值分组

时间:2012-07-20 13:45:33

标签: r

这似乎是一个如此简单的问题,但我一直在努力让这个工作起作用:

鉴于此数据框标识了idcontactcontactGrp分组的互动,

head(data)
   id               sesTs  contact    contactGrp   relpos   maxpos
1 6849 2012-06-25 15:58:34   peter        west    0.000000      3
2 6849 2012-06-25 18:24:49   sarah        south   0.500000      3
3 6849 2012-06-27 00:13:30   sarah        south   1.000000      3
4 1235 2012-06-29 17:49:35   peter        west    0.000000      2
5 1235 2012-06-29 23:56:35   peter        west    1.000000      2
6 5893 2012-06-30 22:21:33   carl         east    0.000000      1

unique(data$contactGrp)relpos=1maxpos>1的联系人数量是多少?

预期结果将是:

1 west   1
2 south  1
3 east   0

我试过的一小部分行:

  • aggregate(data, by=list('contactGrp'), FUN=count)会产生错误,无过滤
  • 使用data.table似乎需要一个密钥,这在此数据中并不是唯一的......
  • ddply(data,"contactGrp",summarise,count=???)无法确定使用哪个函数填充count
  • ddply(subset(data,maxpos>1 & relpos==0), c('contactGrp'), function(df)count(df$relpos))有效但给了我一个额外的列x,感觉就像我过于复杂了......

SQL很简单:Select contactGrp, count(*) as cnt from data where … Group by contactGrp但我正在尝试学习R

4 个答案:

答案 0 :(得分:24)

这是data.table解决方案:

> library(data.table)
> dt <- data.table(sessions)
> dt[, length(contact[relpos == 0 & maxpos > 1]), by = contactGrp]
     contactGrp V1
[1,]       west  2
[2,]      south  0
[3,]       east  0

> dt[, length(contact[relpos == 1 & maxpos > 1]), by = contactGrp]
     contactGrp V1
[1,]       west  1
[2,]      south  1
[3,]       east  0

答案 1 :(得分:20)

我认为这是您正在寻找的ddply版本:

ddply(sessions,.(contactGrp),
      summarise,
      count = length(contact[relpos == 0 & maxpos > 1]))

答案 2 :(得分:11)

您第一次尝试使用聚合的行不起作用,因为没有函数count。你的意思是length。您所要做的就是使用relpos和maxpos的条件数据选择执行该操作,并选择一个虚拟变量来获取计数(无关紧要)。然而,内置的table命令不是使用各种灵活的聚合命令,而是专门为此而设计的。

with( data[data$relpos == 1 & data$maxpos > 1,], table(contactGrp) )

答案 3 :(得分:10)

这是另一种方法:

a <- data.frame(id=1:10, contact=sample(c("peter", "sahrah"), 10, T), contactGrp=sample(c("west", "east"), 10, T), relpos=sample(0:1, 10, T), maxpos=runif(10, 0,10))

library(sqldf)
sqldf("Select contactGrp, count(*) as cnt from a where relpos=0 and maxpos > 1 Group by contactGrp")
  contactGrp cnt
1       east   3
2       west   1