【问题标题】:Merge data frames from a list with each other将列表中的数据框相互合并
【发布时间】:2012-12-06 20:49:27
【问题描述】:

我需要什么:

我有一个巨大的数据框,其中包含以下列(还有一些,但这些并不重要)。这是一个例子:

    user_id video_id group_id    x   y
1         1        0        0   39 108
2         1        0        0   39 108
3         1       10        0  135 180
4         2        0        0   20 123

当然,用户、视频和组 ID 是因素。例如,有 20 个视频,但每个视频对每个用户和组都有几个“观察”。

我想将此数据框转换为以下格式,其中x.Ny.N 的数量与用户数量一样多 (N)。

video_id  x.1   y.1  x.2  y.2  …
       0   39   108   20  123

因此,对于视频 0,来自用户 1 的 x 和 y 值分别位于 x.1y.1 列中。对于用户 2,它们的值位于 x.2y.2 等列中。

我尝试过的:

我为自己制作了一个数据框列表,这些数据框仅由每个 video_id 的所有 x, y 观察组成:

summaryList = dlply(allData, .(user_id), function(x) unique(x[c("video_id","x","y")]) )

看起来是这样的:

List of 15
 $ 1 :'data.frame': 20 obs. of  3 variables:
  ..$ video_id: Factor w/ 20 levels "0","1","2","3",..: 1 11 8 5 12 9 20 13 7 10 ...
  ..$ x       : int [1:20] 39 135 86 122 28 167 203 433 549 490 ...
  ..$ y       : int [1:20] 108 180 164 103 187 128 185 355 360 368 ...
 $ 2 :'data.frame': 20 obs. of  3 variables:
  ..$ video_id: Factor w/ 20 levels "0","1","2","3",..: 2 14 15 4 20 6 19 3 13 18 ...
  ..$ x       : int [1:20] 128 688 435 218 528 362 299 134 83 417 ...
  ..$ y       : int [1:20] 165 117 135 179 96 328 332 563 623 476 ...

我被困在哪里:

剩下要做的是:

  • 基于video_id,将summaryList中的每个数据框相互合并。我找不到访问列表中实际数据帧的好方法,它们是summaryList[1]$`1`summaryList[2]$`2` 等等。

    @James 找到了部分解决方案:

    Reduce(function(x,y) merge(x,y,by="video_id"),summaryList)
    
  • 确保在用户 ID 之后重命名列名,而不是保持原样。现在我的summaryList 不包含有关用户ID 的任何信息,Reduce 的输出有重复的列名,如x.x y.x x.y y.y x.x y.x 等等。

我该怎么做呢?或者有没有比我目前正在做的更简单的方法来获得结果?

【问题讨论】:

  • 您能否提供一部分数据?我在想Reduce(function(x,y) merge(x,y,by="video_id"),summaryList) 可能会成功
  • 您能否提供一个(简化的)您的输入 data.frame 示例和预期输出?我很难理解你想要做什么。
  • @Roland 我添加了一个小例子。这是the whole dataset以防万一。
  • @James 这几乎有效,只有列是video_id x.x y.x x.y y.y x.x y.x等,所以不以用户ID命名。
  • @slhck 之后尝试使用names(reducedData)[-1] <- do.call(function(...) paste(...,sep="."),expand.grid(letters[24:25],names(summaryList)))

标签: r merge dataframe plyr


【解决方案1】:

我还是有些困惑。不过,我猜你只是想meltdcast

library(reshape2)
d <- melt(allData,id.vars=c("user_id","video_id"), measure.vars=c("x","y"))
dcast(d,video_id~user_id+variable,value.var="value",fun.aggregate=mean)

导致:

 video_id  1_x 1_y  2_x 2_y  3_x 3_y  4_x 4_y  5_x 5_y  6_x 6_y  7_x 7_y  8_x 8_y  9_x 9_y 10_x 10_y 11_x 11_y 12_x 12_y 14_x 14_y 15_x 15_y 16_x 16_y
1         0   39 108  899 132   61 357  149 298 1105 415  148 208  442 200  210 134   58 244  910  403  152   52 1092  617 1012  114 1105  424  548  394
2         1 1125  70  128 165 1151 390  171 587  623 623   80 643  866 310  994 114  854 129  781  306  672   -1 1096  354  525  524  150 

【讨论】:

  • 我不得不删除一些额外的专栏,请参阅对您帖子的编辑,但这也有效,谢谢!我对reshape 有点陌生,所以您能否解释一下dcast 在这里做了什么或者为什么它首先创建了这些列?
  • dcast 只是从长格式(最常用于统计软件)转换为宽格式(Excel 人员喜欢)。该公式定义哪些变量成为列标题。 melt是逆变换。
【解决方案2】:

Reduce 成功了:

reducedData <- Reduce(function(x,y) merge(x,y,by="video_id"),summaryList)

...但您需要在之后修复names

names(reducedData)[-1] <- do.call(function(...) paste(...,sep="."),expand.grid(letters[24:25],names(summaryList)))

结果是:

   video_id  x.1 y.1  x.2 y.2  x.3 y.3  x.4 y.4  x.5 y.5  x.6 y.6  x.7 y.7  x.8
1         0   39 108  899 132   61 357  149 298 1105 415  148 208  442 200  210
2         1 1125  70  128 165 1151 390  171 587  623 623   80 643  866 310  994

【讨论】:

    猜你喜欢
    • 2022-01-25
    • 2016-12-20
    • 1970-01-01
    • 2018-11-19
    • 2021-08-28
    • 2022-01-14
    • 2014-10-22
    • 2017-10-21
    • 1970-01-01
    相关资源
    最近更新 更多