2014-02-20 46 views
2

在使用R時,我經常感興趣的是對data.frame執行操作,其中我根據組彙總變量,然後希望將這些彙總值添加回數據。幀。按組拉伸行間彙總值

myDF <- data.frame(A = runif(5), B = c("A", "A", "A", "B", "B")) 
myDF$Total <- with(myDF, by(A, B, sum))[myDF$B] 
myDF$Proportion <- with(myDF, A/Total) 

其產生:這是最容易通過示例所示

  A B  Total Proportion 
1 0.5272734 A 1.7186369 0.3067975 
2 0.5105128 A 1.7186369 0.2970452 
3 0.6808507 A 1.7186369 0.3961574 
4 0.2892025 B 0.6667133 0.4337734 
5 0.3775108 B 0.6667133 0.5662266 

這招 - 基本上獲得指定值的向量,並且「傳播」或跨相關的行「拉伸」他們雖然class(myDF$Total)"array",除非我將by()置於c()之內。

我很納悶:

  1. 是否有此操作的常用名稱?
  2. 是否還有另外一種不太冒昧的感覺和/或更快的做法?
  3. 有沒有辦法用dplyr來做到這一點?也許有哈德利批准的動詞操作(如變異,排列等),我不知道。我知道這很容易summarise(),但我經常需要將這些摘要放回到data.frame中。

回答

11

這裏有一個 「少哈克」 的方式與基地R.

set.seed(1) 
myDF <- data.frame(A = runif(5), B = c("A", "A", "A", "B", "B")) 

within(myDF, { 
    Total <- ave(A, B, FUN = sum) 
    Proportion <- A/Total 
}) 

#   A B Proportion Total 
# 1 0.2655087 A 0.2193406 1.210486 
# 2 0.3721239 A 0.3074170 1.210486 
# 3 0.5728534 A 0.4732425 1.210486 
# 4 0.9082078 B 0.8182865 1.109890 
# 5 0.2016819 B 0.1817135 1.109890 

在 「dplyr」 語言要做到這一點,我想你正在尋找mutate

myDF %>% 
    group_by(B) %>% 
    mutate(Total = sum(A), Proportion = A/Total) 

# Source: local data frame [5 x 4] 
# Groups: B 
# 
#   A B Total Proportion 
# 1 0.2655087 A 1.210486 0.2193406 
# 2 0.3721239 A 1.210486 0.3074170 
# 3 0.5728534 A 1.210486 0.4732425 
# 4 0.9082078 B 1.109890 0.8182865 
# 5 0.2016819 B 1.109890 0.1817135 

從在"Introduction to dplyr" vignette,你會發現下面的描述:

除了塞萊從現有列的集合中,添加新列是現有列的功能通常很有用。這是mutate()的工作。 dplyr::mutate()的作用方式與plyr::mutate()相同,與base::transform()類似。 mutate()transform()之間的主要區別在於mutate允許您引用剛剛創建的列。


而且,既然您已經標記這個 「data.table」,可以在 「鏈」 中的 「data.table」 命令組合在一起很容易做這樣的事情:

DT <- data.table(myDF) 
DT[, Total := sum(A), by = B][, Proportion := A/Total][]