2013-03-01 81 views
5

我對R相當陌生,我試圖用aggregate對數據框,每個主題和數據集中的每個指標執行一些時間序列整形。這工作很好,但我發現結果不是一個非常容易使用的格式。我希望能夠將結果轉換回原始數據幀的相同格式。R聚合函數的結果平展/非規範化

使用虹膜數據集爲例:

# 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做任何事情。

+0

你在談論時代系列..你舉個基於虹膜的例子嗎?!!你聚合使用差異?理由是什麼?它會更好地使用時間序列軟件包(動物園,xts,..)之一!真的我不明白你想要做什麼(我至少讀了3次你的問題) – agstudy 2013-03-01 23:21:28

+1

@agstudy,我*想*這個問題與'aggregate'的行爲有點關係,如果你給它一個像'summary'或'fivenum'或其他可以返回多個列的函數。在這種情況下,結果是*看起來像多列data.frame,但實際上是一個'matrix'作爲'data.frame'中的一列。因此,一個'do.call(data.frame,...)'應該能夠「平坦」輸出。 – A5C1D2H2I1M1N2O1R2T1 2013-03-02 09:54:10

+0

@AnandaMahto謝謝。我明白你的觀點。 – agstudy 2013-03-02 19:39:08

回答

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

2

我可以在這種情況下想到的最好的辦法是data.table

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

如果你想有一個plyr解決方案,那麼這個想法基本上是相同的。按Species拆分並將diff應用於每列。

​​
+0

請問最低選民請解釋原因,以便我可以嘗試糾正它? – Arun 2013-03-05 18:57:39

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 ... 
1

這就是我所理解的你的問題:根據您目前的使用aggregate的方法,你會得到「Sepal.Length」的結果matrix ,「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 ... 

但是,在您的控制檯,顯示作爲什麼看起來data.frame 197列。

要將「iris_diff」轉換爲具有197列的data.frame。這裏是你如何能做到這一點與現有的輸出(一招我從@詹姆斯,here拿起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