2015-05-14 55 views
3

我有以下数据帧鸿沟行值

dat <- data.frame(x=c(1,2,3,3,2,1), y=c(3,4,4,5,2,5)) 

现在我想获得第三列由所述聚集的y值除以在y行值(基于列x中的唯一值)。那么,我得到第1行如下:1,3,0.375; 0.375已计算为3 /(5 + 3)。

我对R比较陌生,希望你能帮助我。谢谢!

回答

13

有解决这个的各种方式,这里有一个

with(dat, ave(y, x, FUN = function(x) x/sum(x))) 
## [1] 0.3750000 0.6666667 0.4444444 0.5555556 0.3333333 0.6250000 

这里的另一种可能性

library(data.table) 
setDT(dat)[, z := y/sum(y), by = x] 
dat 
# x y   z 
# 1: 1 3 0.3750000 
# 2: 2 4 0.6666667 
# 3: 3 4 0.4444444 
# 4: 3 5 0.5555556 
# 5: 2 2 0.3333333 
# 6: 1 5 0.6250000 

这里的第三个

library(dplyr) 
dat %>% 
    group_by(x) %>% 
    mutate(z = y/sum(y)) 

# Source: local data frame [6 x 3] 
# Groups: x 
# 
# x y   z 
# 1 1 3 0.3750000 
# 2 2 4 0.6666667 
# 3 3 4 0.4444444 
# 4 3 5 0.5555556 
# 5 2 2 0.3333333 
# 6 1 5 0.6250000 
+1

'与(DAT,Y/AVE(Y,X,FUN =总和))'会有点更紧凑。另外一个选项'dat $ y/xtabs(y〜x,dat)[dat $ x]' – akrun

+0

因此,在'dplyr'中,'sum'总和由前一个'group_by'创建的组。尝试使用'dat < - data.frame(x = c(1,1,4,4,5,5,6,6),y = c(5,6,1,0,3,1,2,3 )''然后'dat%>>%group_by(x)%>%group_by(y)%>%mutate(w = y/sum(x))'看看'group_by(x)'没有效果。相反,不分组将整个数据框视为组:'dat%>%mutate(w = y/sum(x))'计算总和为1的相对权重。或者'dat%>%mutate(rel_x = x/sum (x))%>%summary(total = sum(rel_x))'产生1,因为它应该。 –

+0

@DavidTonhofer你需要什么? –

1

当然还有对人之路在SQL中思考,在这种情况下非常罗嗦,但很好地概括各种其他类似IAR问题:

library(sqldf) 
dat <- sqldf(" 
    with sums as (
    select 
     x 
     ,sum(y) as sy 
    from dat 
    group by x 
) 
    select 
    d.x 
    ,d.y 
    ,d.y/s.sy as z 
    from dat d 
    inner join sums s 
    on d.x = s.x 
")  
1

这里有一些基础R解决方案:

1)prop.table使用基本prop.table功能与ave这样的:

transform(dat, z = ave(y, x, FUN = prop.table)) 

捐赠:

x y   z 
1 1 3 0.3750000 
2 2 4 0.6666667 
3 3 4 0.4444444 
4 3 5 0.5555556 
5 2 2 0.3333333 
6 1 5 0.6250000 

2)总和这也适用:

transform(dat, z = y/ave(y, x, FUN = sum))