如何ddply()没有排序?

Jam*_*mes 8 sorting r plyr

我使用以下代码汇总我的数据,按复合,复制和质量分组.

summaryDataFrame <- ddply(reviewDataFrame, .(Compound, Replicate, Mass), 
  .fun = calculate_T60_Over_T0_Ratio)
Run Code Online (Sandbox Code Playgroud)

不幸的副作用是生成的数据框按这些字段排序.我想这样做并保持Compound,Replicate和Mass的顺序与原始数据框中的顺序相同.有任何想法吗?我尝试将顺序整数的"排序"列添加到原始数据中,但当然我不能在.variables中包含它,因为我不想'分组'那样,所以它不会在summaryDataFrame.

谢谢您的帮助.

jor*_*ran 11

这一次出现在plyr邮件列表上(由@kohske提出不少),这是由Peter Meil​​strup提供的有限案例的解决方案:

#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 
Run Code Online (Sandbox Code Playgroud)

请阅读Hadley关于为什么这个功能可能不够通用的说明的线程ddply,特别是因为它可能适用于您的情况,因为您可能会返回每个部分更少的行.

编辑包括更一般情况的策略

如果ddply输出的东西按照您不喜欢的顺序排序,则基本上有两个选项:预先使用有序因子指定拆分变量的所需顺序,或者在事后手动对输出进行排序.

例如,请考虑以下数据:

d <- data.frame(x1 = rep(letters[1:3],each = 5), 
                x2 = rep(letters[4:6],5),
                x3 = 1:15,stringsAsFactors = FALSE)
Run Code Online (Sandbox Code Playgroud)

现在使用字符串.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
Run Code Online (Sandbox Code Playgroud)

如果结果数据框没有按"正确"顺序结束,那可能是因为你真的希望其中一些变量是有序因子.假设我们真的想要x1x2订购如下:

d$x1 <- factor(d$x1, levels = c('b','a','c'),ordered = TRUE)
d$x2 <- factor(d$x2, levels = c('d','f','e'), ordered = TRUE)
Run Code Online (Sandbox Code Playgroud)

现在,当我们使用时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
Run Code Online (Sandbox Code Playgroud)

这里的故事的寓意是,如果ddply按照你不想要的顺序输出某些东西,那么你应该使用有序因子来分析你正在分裂的变量,这是一个好兆头.