按条件子集数据

时间:2012-04-27 09:33:04

标签: r split subset plyr

我正在尝试重塑/减少我的数据。到目前为止,我使用for循环(非常慢),但根据我的看法,这应该与Plyr相当快。

我有很多团体(公司,作为数据集中的一个因素),我想完全放弃每个公司,在任何公司的单元格中显示value的0条目。因此,我创建了一个新的data.frame,但遗漏了所有在value处显示0的组。

for循环:

Data Creation:

set.seed(1) 
mydf <- data.frame(firmname = sample(LETTERS[1:5], 40, replace = TRUE), 
        value = rpois(40, 2))

-----------------------------
splitby = mydf$firmname


new.data <- data.frame()

for (i in 1:(length(unique(splitby)))) {
temp <- subset(mydf, splitby == as.character(paste(unique(splitby)[i]))) 
    if (all(temp$value > 0) == "TRUE") {     
    new.data <- rbind(new.data, temp) 
} 
} 

Delete all empty firm factors 
new.data$splitby <- factor(new.data$splitby)

有没有办法通过plyr包实现这一目标?可以在该上下文中使用subset函数吗?

编辑为了复制问题,增加了BenBarnes建议的数据创建。本,非常感谢你。此外,我的代码也经过修改,以符合下面提供的答案。

1 个答案:

答案 0 :(得分:5)

您可以为.fun中的ddply()参数提供匿名函数:

set.seed(1)

mydf <- data.frame(firmname = sample(LETTERS[1:5], 40, replace = TRUE),
  value = rpois(40, 2))

library(plyr)

ddply(mydf,.(firmname), function(x) if(any(x$value==0)) NULL else x )

或者按照Andrie的建议使用[

firms0 <- unique(mydf$firmname[which(mydf$value == 0)])

mydf[-which(mydf$firmname %in% firms0), ]

请注意,ddply的结果按照firmname

进行排序

修改

对于评论中的示例,此方法再次比使用ddply()子集更快,仅选择具有三个以上条目的公司:

firmTable <- table(mydf$firmname)

firmsGT3 <- names(firmTable)[firmTable > 3]

mydf[mydf$firmname %in% firmsGT3, ]