我想知道如何使用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)
有什么想法吗?提前谢谢。
答案 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))
结果是一样的。