如何在没有排序的情况下使用ddply()?

如何在没有排序的情况下使用ddply()?

问题描述:

我使用以下代码来概括我的数据,通过使化合物,复制和质谱进行分组。如何在没有排序的情况下使用ddply()?

summaryDataFrame <- ddply(reviewDataFrame, .(Compound, Replicate, Mass), 
    .fun = calculate_T60_Over_T0_Ratio) 

一个不幸的副作用是,所得到的数据帧由那些字段排序。我想这样做,并保持化合物,复制品和质量与原始数据框中的顺序相同。有任何想法吗?我试着向原始数据添加一个“Sorting”顺序整数列,但是当然我不能在.variables中包含它,因为我不想按'分组',所以它不会返回到summaryDataFrame。

感谢您的帮助。

+0

这与'write.table'无关;标题应该改变。 –

这来了个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 

请务必阅读thread为哈德利的关于为什么这个功能可能不够普遍以至于无法卷入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 

,有可能是因为你真的想一些那些变量被排序的因素。假设我们真的很想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) 

现在,当我们使用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按照您不打算的顺序输出内容,这是一个好兆头,您应该使用有序因子来分解您正在分解的变量。

+0

谢谢。这似乎对我“几乎”起作用。如何将'.sortColumn'保存在函数的返回数据中? 'calculate_T60_Over_T0_Ratio James

+0

@James如果你想在结果中保留'.sortColumn',你可能只需从'keeping.order'中省略'out [,col] joran

+0

对不起,我不清楚。我收到'keeping.order'的错误,因为'.sortColumn'没有被我的函数返回(见上文)。 – James

我最终最终在原始数据框中添加了“索引”列。它由两列pastedsep="_"组成。然后,我又创建了另一个数据框,该数据框仅由'索引'列的unique成员和一个计数器1:length(df)组成。我对返回排序数据帧的数据做了ddply()。然后以原始顺序重新获取数据,我做了merge()结果数据框和索引数据框(确保列的名称相同,这使得这更容易)。最后,我做了order并删除了无关的列。

不是一个优雅的解决方案,而是一个有效的解决方案。

感谢您的协助。它让我思考着正确的方向。