2014-02-20 51 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][]