如何根据每三行中存在的值创建百分比列?

How to create a percentage column based on the values present in every third row?

我有一个包含权重值的数据框。我创建了一个新列,重量百分比变化,其中分母取每三行的值。

df <- data.frame(weight = c(30,30,109,30,309,10,20,20,14))

# expected output
change_of_weight = c(30/109, 30/109, 109/109, 30/10,309/10,10/10,20/14,20/14,14/14)

子集 weight 列的位置 %% 3 为零,rep将每个值吃掉三次。

df <- transform(df, change_of_weight=weight / rep(weight[1:nrow(df) %% 3 == 0], each=3))
df
  weight change_of_weight
1     30        0.2752294
2     30        0.2752294
3    109        1.0000000
4     30        3.0000000
5    309       30.9000000
6     10        1.0000000
7     20        1.4285714
8     20        1.4285714
9     14        1.0000000

您可以每 3 行创建一个组,然后将 weight 列除以组中的最后一个值。

df$change <- with(df, ave(df$weight, ceiling(seq_len(nrow(df))/3), 
                      FUN = function(x) x/x[length(x)]))

或使用dplyr

library(dplyr)
df %>%
  group_by(grp = ceiling(row_number()/3)) %>%
  mutate(change = weight/last(weight))

#  weight   grp change
#   <dbl> <dbl>  <dbl>
#1     30     1  0.275
#2     30     1  0.275
#3    109     1  1    
#4     30     2  3    
#5    309     2 30.9  
#6     10     2  1    
#7     20     3  1.43 
#8     20     3  1.43 
#9     14     3  1    

我们也可以使用gl创建分组列

library(dplyr)
df %>%
   group_by(grp = as.integer(gl(n(), 3, n()))) %>%
   mutate(change = weight/last(weight))
# A tibble: 9 x 3
# Groups:   grp [3]
#  weight   grp change
#   <dbl> <int>  <dbl>
#1     30     1  0.275
#2     30     1  0.275
#3    109     1  1    
#4     30     2  3    
#5    309     2 30.9  
#6     10     2  1    
#7     20     3  1.43 
#8     20     3  1.43 
#9     14     3  1    

或使用data.table

library(data.table)
setDT(df)[, change := weight/last(weight), .(as.integer(gl(nrow(df), 3, nrow(df))))]