使用plyr daply将数据帧转换为矩阵

JD *_*ici 7 r plyr dataframe

我正在尝试使用包中的daply函数,plyr但我无法正确输出.即使构成矩阵的变量是数字,矩阵的元素也是列表,而不是变量本身.这是一小部分数据,例如:

   Month Vehicle Samples
1 Oct-10   31057     256
2 Oct-10   31059     316
3 Oct-10   31060     348
4 Nov-10   31057     267
5 Nov-10   31059     293
6 Nov-10   31060     250
7 Dec-10   31057     159
8 Dec-10   31059     268
9 Dec-10   31060     206
Run Code Online (Sandbox Code Playgroud)

我希望能够以矩阵格式可视化数据,这看起来像这样:

  Month
Vehicle Oct-10 Nov-10 Dec-10
  31057    256    267    159
  31059    316    293    268
  31060    348    250    206
Run Code Online (Sandbox Code Playgroud)

这里有一些我使用的替代语法(后者因为我的原始数据框有比我在这里显示的更多的列):

daply(DF, .(Vehicle, Month), identity)
daply(DF,.(Vehicle,Month), colwise(identity,.(Samples)))
Run Code Online (Sandbox Code Playgroud)

然而,我得到的是相当深奥的:

       Month
Vehicle Oct-10 Nov-10 Dec-10
  31057 List,3 List,3 List,3
  31059 List,3 List,3 List,3
  31060 List,3 List,3 List,3
Run Code Online (Sandbox Code Playgroud)

str在输出中使用了一些评论者建议的功能,这里有一段摘录:

List of 9
 $ :'data.frame':       1 obs. of  3 variables:
  ..$ Month  : Ord.factor w/ 3 levels "Oct-10"<"Nov-10"<..: 1
  ..$ Vehicle: Factor w/ 3 levels "31057","31059",..: 1
  ..$ Samples: int 256
 $ :'data.frame':       1 obs. of  3 variables:
  ..$ Month  : Ord.factor w/ 3 levels "Oct-10"<"Nov-10"<..: 1
  ..$ Vehicle: Factor w/ 3 levels "31057","31059",..: 2
  ..$ Samples: int 316
Run Code Online (Sandbox Code Playgroud)

我错过了什么?另外,有没有办法简单地使用基础包?谢谢!

Dput如果您想重现这个数据框,则下面是数据框:

structure(list(Month = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 
3L, 3L), .Label = c("Oct-10", "Nov-10", "Dec-10"), class = c("ordered", 
"factor")), Vehicle = structure(c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 
2L, 3L), .Label = c("31057", "31059", "31060"), class = "factor"), 
    Samples = c(256L, 316L, 348L, 267L, 293L, 250L, 159L, 268L, 
    206L)), .Names = c("Month", "Vehicle", "Samples"), class = "data.frame", row.names = c(NA, 
9L))
Run Code Online (Sandbox Code Playgroud)

Aar*_*ica 7

这个identity功能不是你想要的; 在帮助页面中,"所有plyr函数使用相同的split-apply-combine策略:它们将输入分成更简单的部分,将.fun应用于每个部分,然后将这些部分组合成单个数据结构." 在这种情况下,较简单的部分是原始数据框的子集,具有独特的车辆/月组合; identity函数只返回该子集,然后使用这些子集填充结果矩阵.

也就是说,您获得的矩阵的每个元素都是一个数据框(这是一种列表),其行具有月/车组合.

> try1 <- daply(DF, .(Vehicle, Month), identity)
> try1[1,1]
[[1]]
   Month Vehicle Samples
1 Oct-10   31057     256
Run Code Online (Sandbox Code Playgroud)

你想要使用一个只获取该Samples数据框部分的函数,如下所示:

daply(DF, .(Vehicle, Month), function(x) x$Samples)
Run Code Online (Sandbox Code Playgroud)

结果

       Month
Vehicle Oct-10 Nov-10 Dec-10
  31057    256    267    159
  31059    316    293    268
  31060    348    250    206
Run Code Online (Sandbox Code Playgroud)

执行此操作的一些替代方法是castreshape包(返回数据框)开始

cast(DF, Vehicle~Month, value="Samples")
Run Code Online (Sandbox Code Playgroud)

修改后的版本reshape2; 第一个返回数据帧,第二个返回矩阵

dcast(DF, Vehicle~Month, value_var="Samples")
acast(DF, Vehicle~Month, value_var="Samples")
Run Code Online (Sandbox Code Playgroud)

xtabsstats

xtabs(Samples ~ Vehicle + Month, DF)
Run Code Online (Sandbox Code Playgroud)

或者手工,使用矩阵索引并不难; 几乎所有代码都只是设置矩阵.

with(DF, {
  out <- matrix(nrow=nlevels(Vehicle), ncol=nlevels(Month),
                dimnames=list(Vehicle=levels(Vehicle), Month=levels(Month)))
  out[cbind(Vehicle, Month)] <- Samples
  out
})
Run Code Online (Sandbox Code Playgroud)

reshape在统计数据包功能也可以用来做这个,但语法是困难的,我并没有因为学习使用一次它castmeltreshape包.