如何将“by”数据结构转换为带有因子的data.frame

时间:2014-09-03 17:53:56

标签: r dataframe

我想把data.frame列中的一些列作为因子,通过因子分组以复杂的方式对其进行汇总,然后将结果汇总到一个新的汇总data.frame.这必须是人们的事情。一直这么做,但我似乎无法做到。这是我想要做的事情的简化示例:

> df
  direction distance
1     south 83.40364
2      east 38.45644
3      west 92.29418
4      east 87.81878
5     north 99.62949
6      west 10.65441
7     south 58.06977
8     north 79.34895
> bydir <- by(df,df$direction,function(x) {
    list(dir=x$direction[1], dist=sum(x$distance))})
> dirs <- data.frame()
> for (i in bydir) {dirs <- rbind(dirs, i)}
Warning messages:
1: In `[<-.factor`(`*tmp*`, ri, value = "north") :
  invalid factor level, NA generated
2: In `[<-.factor`(`*tmp*`, ri, value = "south") :
  invalid factor level, NA generated
3: In `[<-.factor`(`*tmp*`, ri, value = "west") :
  invalid factor level, NA generated
> dirs
    dir     dist
2  east 126.2752
21 <NA> 178.9784
3  <NA> 141.4734
4  <NA> 102.9486

我已经看了plyr一点,我打赌我可以让它为我工作,但我真正的问题是为什么不能接受{{1}的新值因为我不是一次构建一个data.frame,因此不是有效级别的因素,只是为因子添加级别?即使将因子转换为dir并在character中设置stringsAsFactors = FALSE,也不会阻止R尝试将该列作为因素并生成NA。我想要一个解决方案,但更重要的是,我想了解R在这里做了什么。

谢谢,

格伦

P.S。我在这里找到了一些有趣的指示:http://lamages.blogspot.com/2012/01/say-it-in-r-with-by-apply-and-friends.html但我还没有让他们中的任何一个为我的案子工作。

1 个答案:

答案 0 :(得分:2)

问题在于你的循环。您无法轻松地绑定到没有列的空data.frame。幸运的是,这是完全可以避免的。

bydir <- by(df,df$direction,function(x) {
    list(dir=x$direction[1], dist=sum(x$distance))})
do.call(rbind.data.frame, bydir)

更好。返回data.frame而不是通用列表

会更好
bydir <- by(df,df$direction,function(x) {
    data.frame(dir=x$direction[1], dist=sum(x$distance))})
do.call(rbind, bydir)

当然,by()对于这个特定的例子来说太过分了。一个简单的aggregate会做

aggregate(distance~direction, df, sum)

但我认为你的真实场景更复杂。