使用组内的第一个元素对所有行进行标准化

问题描述:

是否有一种优雅的方法用dplyr标准化具有组特定标准的列?使用组内的第一个元素对所有行进行标准化

实施例: 我有一个数据帧:

df = data.frame(year=c(1:2, 1:2), 
       group=c("a", "a", "b", "b"), 
       val=c(100, 200, 300, 900)) 

即:

year group val 
1 1  a 100 
2 2  a 200 
3 1  b 300 
4 2  b 900 

我想通过在一年= 1给定组的值来标准化val。期望的输出:

year group val val_norm 
1 1  a 100  1 
2 2  a 200  2 
3 1  b 300  1 
4 2  b 900  3 

例如,在第4行norm = 300(year == 1 & group ==“b”)因此val_norm = 900/300 = 3.

我可以通过只用规范提取一个辅助数据帧然后做一个左侧加入原始数据框。

什么是更优雅的方式来实现这一点,而不创建临时数据框?

我们可以按'组'分组,然后用val'除'年'为1的'val'(year==1)。在这里,我选择了第一个观察结果(如果每个'组'有1个重复'年份')。

library(dplyr) 
df %>% 
    group_by(group) %>% 
    mutate(val_norm = val/val[year==1][1L]) 
#  year group val val_norm 
# <int> <fctr> <dbl> <dbl> 
#1  1  a 100  1 
#2  2  a 200  2 
#3  1  b 300  1 
#4  2  b 900  3 

如果我们需要的优雅和效率,data.table可以尝试

library(data.table) 
setDT(df)[, val_norm := val/val[year==1][1L] , by = group] 
+2

优秀。我不知道可以在mutate([year == 1])中进行子选择。这很棒。也感谢data.table奖金。 – user673592

+0

@donlelek你在这个例子中是正确的,但如果'year'没有被排序,它可能会失败。 – akrun