5

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

以 iris 数据集为例:

# 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,但我会接受在plyror中执行所有操作的解决方案reshape

4

4 回答 4

2

在这种情况下,我能想到的最佳解决方案是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)))
于 2013-03-02T00:15:26.460 回答
1

这是我理解为您的问题:使用您当前的使用方法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”转换为data.frame具有 197 列的 a。以下是如何使用现有输出来做到这一点(我从@James 那里学到的一个技巧,这里是 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
于 2013-03-02T09:51:38.973 回答
1

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

您可以将其拆分by以获取数据(行数少于 in 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)使用它,因为这可以满足您对矩阵的要求(但不适用于数据帧)。关键是该函数返回的行数与每个Speciesin 中的行数不同iris

于 2013-03-01T23:34:07.827 回答
1

如果你想返回某种与输入向量长度相同的一阶差分向量,你应该使用 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 ...
于 2013-03-02T02:12:59.447 回答