【问题标题】:Flatten/denormalize the result of the R aggregate function展平/非规范化 R 聚合函数的结果
【发布时间】:2013-02-16 13:34:27
【问题描述】:

我对 R 相当陌生,我正在尝试使用 aggregate 对数据帧、每个主题和我的数据集中的每个指标执行一些时间序列整形。这很好用,但我发现结果不是很容易使用的格式。我希望能够将结果转换回与原始数据框相同的格式。

以鸢尾花数据集为例:

# Split into two data frames, one for metrics, the other for grouping
iris_species = subset(iris, select=Species)
iris_metrics = subset(iris, select=-Species)
# Compute diff for each metric with respect to its species
iris_diff = aggregate(iris_metrics, iris_species, diff)

我只是使用diff 来说明我有一个塑造时间序列的函数,因此我得到了一个可能不同长度的时间序列,并且绝对不是一个聚合值(例如平均值)。

我想将结果转换为原始的“平面”数据框,这似乎是一个矩阵,其中列出了值单元格。

我很好奇如何使用来自 aggregate 的结果来管理这个问题,但我可以使用在 plyrreshape 中执行所有操作的解决方案。

【问题讨论】:

  • 你说的是时间序列..你举了一个基于iris的例子?!你聚合使用差异?理由是什么..最好使用时间序列包之一(动物园,xts,..)!真的我不明白你想做什么。(我至少读了3次你的问题)
  • @agstudy,我认为这个问题有点与aggregate 的行为有关,如果你给它一个像summaryfivenum 之类的函数否则将返回多于一列。在这种情况下,结果看起来类似于多列data.frame,但实际上是matrix 作为data.frame 中的一列。因此,do.call(data.frame, ...) 应该可以“展平”输出。
  • @AnandaMahto 谢谢。我明白你的意思。

标签: r aggregate plyr reshape


【解决方案1】:

在这种情况下我能想到的最佳解决方案是data.table

require(data.table)
dt <- data.table(iris, key="Species")
dt.out <- dt[, lapply(.SD, diff), by=Species]

如果你想要一个plyr 解决方案,那么这个想法基本上是一样的。按Species 拆分并将diff 应用于每一列。

require(plyr)
ddply(iris, .(Species), function(x) do.call(cbind, lapply(x[,1:4], diff)))

【讨论】:

  • 投反对票的人能否解释一下原因,以便我尝试纠正它??
【解决方案2】:

您可能知道,aggregate 一次只处理一列。需要一个值,如果返回长度不同于 1 的向量,就会发生奇怪的事情。

您可以将其与by 拆分以获取数据(比iris 中的行少)并将其重新组合在一起:

b <- by(iris_metrics, iris_species, FUN=function(x) diff(as.matrix(x)))
do.call(rbind, lapply(names(b), function(x) data.frame(Species=x, b[[x]])))

diff(as.matrix) 用于矩阵(但不适用于数据帧)。关键是该函数返回的行数与iris 中的每个Species 中的行数不同。

【讨论】:

    【解决方案3】:

    如果您想返回某种与输入向量长度相同的一阶差分向量,您应该使用 ave 和匿名函数来执行此操作。由于diff 返回一个不同长度的向量,因此您需要使用 NA(或您选择的标记)对其进行扩展。

    iris_diff = lapply(iris_metrics, 
            function(xx) ave(xx, iris_species, FUN=function(x) c(NA, diff(x) ) )  )
    str(iris_diff)
    #--------------
    List of 4
     $ Sepal.Length: num [1:150] NA -0.2 -0.2 -0.1 0.4 ...
     $ Sepal.Width : num [1:150] NA -0.5 0.2 -0.1 0.5 0.3 -0.5 0 -0.5 0.2 ...
     $ Petal.Length: num [1:150] NA 0 -0.1 0.2 -0.1 ...
     $ Petal.Width : num [1:150] NA 0 0 0 0 0.2 -0.1 -0.1 0 -0.1 ...
    

    如果您希望将其作为数据框,只需将 data.frame 包裹起来即可。包含原始分组向量是个好主意:

    iris_diff <- data.frame( Species= iris_species, iris_diff)
    str(iris_diff)
    #------
    'data.frame':   150 obs. of  5 variables:
     $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...
     $ Sepal.Length: num  NA -0.2 -0.2 -0.1 0.4 ...
     $ Sepal.Width : num  NA -0.5 0.2 -0.1 0.5 0.3 -0.5 0 -0.5 0.2 ...
     $ Petal.Length: num  NA 0 -0.1 0.2 -0.1 ...
     $ Petal.Width : num  NA 0 0 0 0 0.2 -0.1 -0.1 0 -0.1 ...
    

    【讨论】:

      【解决方案4】:

      以下是我对您的问题的理解:使用您当前使用 aggregate 的方法,您会得到一个 matrix 来表示“Sepal.Length”、“Sepal.Width”等的结果。

      > str(iris_diff)
      'data.frame':   3 obs. of  5 variables:
       $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 2 3
       $ Sepal.Length: num [1:3, 1:49] -0.2 -0.6 -0.5 -0.2 0.5 ...
       $ Sepal.Width : num [1:3, 1:49] -0.5 0 -0.6 0.2 -0.1 0.3 -0.1 -0.8 -0.1 0.5 ...
       $ Petal.Length: num [1:3, 1:49] 0 -0.2 -0.9 -0.1 0.4 ...
       $ Petal.Width : num [1:3, 1:49] 0 0.1 -0.6 0 0 0.2 0 -0.2 -0.3 0 ...
      

      但是,在您的控制台中,它显示为 看起来 类似于具有 197 列的 data.frame

      您想将“iris_diff”转换为具有 197 列的 data.frame。以下是如何使用现有输出来做到这一点(我从@James,here on SO 那里学到的一个技巧):

      do.call(data.frame, iris_diff)
      

      以下是我们查看该操作的str 时输出的前几行:

      > str(do.call(data.frame, iris_diff))
      'data.frame':   3 obs. of  197 variables:
       $ Species        : Factor w/ 3 levels "setosa","versicolor",..: 1 2 3
       $ Sepal.Length.1 : num  -0.2 -0.6 -0.5
       $ Sepal.Length.2 : num  -0.2 0.5 1.3
       $ Sepal.Length.3 : num  -0.1 -1.4 -0.8
       $ Sepal.Length.4 : num  0.4 1 0.2
       $ Sepal.Length.5 : num  0.4 -0.8 1.1
       $ Sepal.Length.6 : num  -0.8 0.6 -2.7
       $ Sepal.Length.7 : num  0.4 -1.4 2.4
       $ Sepal.Length.8 : num  -0.6 1.7 -0.6
       $ Sepal.Length.9 : num  0.5 -1.4 0.5
       $ Sepal.Length.10: num  0.5 -0.2 -0.7
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-16
        • 1970-01-01
        • 2019-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-03
        • 2011-03-14
        相关资源
        最近更新 更多