使用plyr拆分,子集拆分,然后应用函数并组合

时间:2014-06-25 20:32:40

标签: r plyr

我想知道如何使用plyr来分割我拥有的数据,然后使用分割的子集,然后应用我想要的功能,然后再次组合所有内容。我想,一个例子可以解释我想要做得更好的事情。

以下是我到目前为止所做的事情(包括补充数据)。这只是从一开始就从整个数据集中删除了异常值,这些异常值的定义是平均值大于2个标准偏差。

library(plyr)

# create some random data
d <- data.frame(type1 = c(rep("A",100),rep("B",50),rep("C",50)), 
                type2 = c(rep("good",65),rep("bad",135)),
                values = rnorm(200, 10, 5))

# remove values more than 2 standard deviations from the mean
mu <- mean(d$values)
stdev <- sd(d$values)
d_nooutliers <- subset(subset(d, values > mu - 2*stdev), values < mu + 2*stdev)

# breakdown by type1 and type2
my_breakdown <- ddply(d_nooutliers, .(type1, type2), summarize,
                      mean = mean(values), sd = sd(values), n = length(values))

问题是,上面的方法删除了整个数据集的异常值。相反,我想从每次拆分中删除异常值。例如,当plyr查看“A”和“good”值的拆分时,我想计算该组中值的平均值和标准差,然后删除异常值上面的方法,然后在删除异常值并重新组合所有内容后重新计算均值和标准。

这相当于运行下面的代码。但是,这是一种手动方式,我显然希望使用plyr,因为在我的实际数据中,手动方法会编写大量不必要的代码。

d_A_good <- subset(subset(d, type1 == "A"), type2 == "good")
d_A_mu <- mean(d_A_good$values)
d_A_stdev <- sd(d_A_good$values)
d_A_good_nooutliers <- subset(subset(d_A_good, values > d_A_mu - 2*d_A_stdev), 
                              values < d_A_mu + 2*d_A_stdev)
mean_i_want <- mean(d_A_good_nooutliers$values)
sd_i_want <- sd(d_A_good_nooutliers$values)

有什么想法吗?提前谢谢。

1 个答案:

答案 0 :(得分:3)

以下是使用dplyr执行此操作的方法,该方法也比plyr更快:

require(dplyr)

d %>% 
  group_by(type1, type2) %>%
  mutate(mu = mean(values),
         stdev = sd(values)) %>%
  filter(values > mu - 2*stdev, values < mu + 2*stdev) %>%
  summarize(mu = mean(values),
            stdev = sd(values))

#Source: local data frame [4 x 4]
#Groups: type1
#
#  type1 type2       mu   stdev
#1     A   bad 10.399257 4.797609
#2     A  good  9.172753 3.905397
#3     B   bad 10.167619 4.748708
#4     C   bad  7.983228 4.613134

修改

如果你在过滤器中包含mutate中的内容,你可以写得更短一些:

d %>% 
  group_by(type1, type2) %>%
  filter(values > mean(values) - 2*sd(values), 
         values < mean(values) + 2*sd(values)) %>%
  summarize(mu = mean(values),
            stdev = sd(values))

结果是一样的。