我使用以下代码汇总我的数据,按复合,复制和质量分组。
summaryDataFrame <- ddply(reviewDataFrame, .(Compound, Replicate, Mass),
.fun = calculate_T60_Over_T0_Ratio)
不幸的副作用是生成的数据框按这些字段排序。我想这样做并保持Compound,Replicate和Mass的顺序与原始数据框中的顺序相同。有任何想法吗?我尝试将顺序整数的“排序”列添加到原始数据中,但当然我不能在.variables中包含它,因为我不想'分组'那样,所以它不会在summaryDataFrame。
感谢您的帮助。
答案 0 :(得分:11)
这一次出现在plyr
邮件列表上(由@kohske提出不少),这是Peter Meilstrup针对有限案例提供的解决方案:
#Peter's version used a function gensym to
# create the col name, but I couldn't track down
# what package it was in.
keeping.order <- function(data, fn, ...) {
col <- ".sortColumn"
data[,col] <- 1:nrow(data)
out <- fn(data, ...)
if (!col %in% colnames(out)) stop("Ordering column not preserved by function")
out <- out[order(out[,col]),]
out[,col] <- NULL
out
}
#Some sample data
d <- structure(list(g = c(2L, 2L, 1L, 1L, 2L, 2L), v = c(-1.90127112738315,
-1.20862680183042, -1.13913266070505, 0.14899803094742, -0.69427656843677,
0.872558638137971)), .Names = c("g", "v"), row.names = c(NA,
-6L), class = "data.frame")
#This one resorts
ddply(d, .(g), mutate, v=scale(v)) #does not preserve order of d
#This one does not
keeping.order(d, ddply, .(g), mutate, v=scale(v)) #preserves order of d
请阅读thread,了解Hadley关于为什么这个功能可能不够通用ddply
的说明,特别是因为它可能适用于您的情况,因为您可能会返回较少的行片。
已编辑为包含更一般案例的策略
如果ddply
正在输出按您不喜欢的顺序排序的内容,则基本上有两个选项:预先使用有序因子指定拆分变量的所需顺序,或者在事实之后手动对输出进行排序。
例如,请考虑以下数据:
d <- data.frame(x1 = rep(letters[1:3],each = 5),
x2 = rep(letters[4:6],5),
x3 = 1:15,stringsAsFactors = FALSE)
现在使用字符串。 ddply
将对输出进行排序,在这种情况下将需要默认的词法排序:
> ddply(d,.(x1,x2),summarise, val = sum(x3))
x1 x2 val
1 a d 5
2 a e 7
3 a f 3
4 b d 17
5 b e 8
6 b f 15
7 c d 13
8 c e 25
9 c f 27
> ddply(d[sample(1:15,15),],.(x1,x2),summarise, val = sum(x3))
x1 x2 val
1 a d 5
2 a e 7
3 a f 3
4 b d 17
5 b e 8
6 b f 15
7 c d 13
8 c e 25
9 c f 27
如果结果数据框没有按“正确”顺序结束,那可能是因为你真的希望其中一些变量是有序因子。假设我们真的想要x1
和x2
这样订购:
d$x1 <- factor(d$x1, levels = c('b','a','c'),ordered = TRUE)
d$x2 <- factor(d$x2, levels = c('d','f','e'), ordered = TRUE)
现在,当我们使用ddply
时,结果排序将如我们所希望的那样:
> ddply(d,.(x1,x2),summarise, val = sum(x3))
x1 x2 val
1 b d 17
2 b f 15
3 b e 8
4 a d 5
5 a f 3
6 a e 7
7 c d 13
8 c f 27
9 c e 25
这里的故事的寓意是,如果ddply
按照你不想要的顺序输出某些东西,那么你应该使用有序因子来表示你要分裂的变量。< / p>
答案 1 :(得分:1)
我最终最终在原始数据框中添加了“索引”列。它由两列pasted
和sep="_"
组成。然后,我创建了另一个数据框,该数据框仅由“索引”列的unique
成员和计数器1:length(df)
组成。我对返回排序数据框的数据执行了ddply()
。然后以原始顺序重新开始,我做了merge()
结果数据框和索引数据框(确保列被命名为相同的东西使这更容易)。最后,我做了order
并删除了无关的列。
不是一个优雅的解决方案,而是一个有效的解决方案。
谢谢你的帮助。它让我思考正确的方向。