2014-12-05 186 views
1

我有三列的data.frame的關鍵如何總結一列:基於其他兩列

To  Amount Type 
Smith $1  A 
John $5  B 
Jeff $8  A 
Smith $4  C 
... ...  ... 

,我需要將其轉換成數據幀表示每種類型的多少錢每個人都收到。

Name TotalAmtOfTypeA TotalAmtOfTypeB TotalAmtOfTypeC ... 
Smith $1    $0    $4 
John $0    $5    $0 
Jeff $8    $0    $0 
... 

原始數據幀長度超過300萬行,因此解決方案效率越高或並行化越好。該解決方案涉及aggregate?或者我應該看看plyr?任何指導將非常感謝!

+0

這個解決方案涉及到「重塑」數據框架,有一個基本的R'reshape'函數,但是如果你想學習dplyr家族工具,使用的包是'tidyr'(它與'dplyr'是互補的)。看看函數'spread()' – konvas 2014-12-05 08:49:57

回答

2

這裏有兩種選擇:

library(tidyr) 
spread(df, Type, Amount) 
#  To ordered.A ordered.B ordered.C 
#1 Jeff  $8  <NA>  <NA> 
#2 John  <NA>  $5  <NA> 
#3 Smith  $1  <NA>  $4 

或者

library(reshape2) 
dcast(df, To ~ Type, value.var = "Amount") 
#  To A B C 
#1 Jeff $8 <NA> <NA> 
#2 John <NA> $5 <NA> 
#3 Smith $1 <NA> $4 

或者,如果你從要素到字符更改列類,你可以這樣做:

df$Amount <- as.character(df$Amount) 
dcast(df, To ~ Type, value.var = "Amount", fill = "$0") 
#  To A B C 
#1 Jeff $8 $0 $0 
#2 John $0 $5 $0 
#3 Smith $1 $0 $4 

,同樣

spread(df, Type, Amount, fill = "$0") 
#  To A B C 
#1 Jeff $8 $0 $0 
#2 John $0 $5 $0 
#3 Smith $1 $0 $4 

注意:如果你離開了「金額」欄的因素,並嘗試使用fill = "$0"你會得到這樣的錯誤消息:

Warning message: In [<-.factor (*tmp* , is.na(ordered), value = 0) : invalid factor level, NA generated


如果你想擺脫那些「$」的在金額欄,這樣就可以真正使用這些數字進行進一步的處理,這裏是你如何能做到這一點的dplyr/tidyr鏈:

library(dplyr) 
library(tidyr) 
df %>% 
    mutate(Amount = as.numeric(gsub("\\$", "", Amount))) %>% 
    spread(Type, Amount, fill = 0) 

#  To A B C 
#1 Jeff 8 0 0 
#2 John 0 5 0 
#3 Smith 1 0 4 
2

這裏有一個data.table解決方案,它應該工作大鼠她快:

數據

library(data.table) 
n <- 1e6 
dat <- data.table(Name = LETTERS[sample(26, n, TRUE)], 
        Amount = rpois(n, 100), 
        Type = letters[sample(26, n, TRUE)]) 

代碼

setkey(dat, Name, Type) 
dat.agg <- dat[, .(Sum = sum(Amount)), by =.(Name, Type)] 
dat.agg[, as.list(setattr(Sum, 'names', Type)), by = .(Name)] 

說明

第一[.data.table聚集TEH data.table擁有的所有的款項組合。第二個[.data.table,以您想要的方式格式化data.tablesetattr用於輸出一個很好的數據(根據Type的級別對列進行賦值)

+0

這看起來確實是在正確的軌道上,但是用我的真實數據,我在['.data.table \'(pacdons2.agg,as.list(setattr(Sum,「names」,: j)中的錯誤不會計算爲每個組的列數相同' – eiowmqui 2014-12-05 17:53:30