按组组织和获取 DF 中的平均值。 R

Organizing and obtaining averages in a DF by a group. R

我有以下数据结构:

iid <- c(rep("I1", 5), rep("I2", 5), rep("I3", 5), rep("I4", 5))
days <- c(-2,-3,0,-1,-5,-1,1,2,1,1,-2,2,2,-3,8,0,0,0,2,1)
val <- c(22,30,41,52,21,32,41,54,21,45,
         11,10,12,15,58,55,32,68,74,85)
data <- data.frame(iid = iid, days = days, val = val)

我需要获取一个新的DF来汇总不同的信息:

  1. 按 iid 分组,即接近 0 的日期(绝对值):对于 iid = I1 将为 0,对于 iid = I2 将为 1,对于 iid = I3 将为 2.
  2. Select 那些接近 0 的日子。在 iid = I1 中将是行 = 3。对于 iid = I2 将是行 = 6、7、9 和 10。
  3. 根据第 2 步获取变量“val”的主要值,以防每个 iid selected 不同的行。例如,I2 应该是 32、41、21 和 45 = 34.75 的平均值。
  4. 根据结果获得一个新的 DF

因此,生成的数据框应如下所示:

iid<-c("I1","I2","I3","I4")
days_r<-c(0,1,2,0)
val_r<-c(41,34.75,11,51.667)
data <- data.frame(iid = iid, days = days_r, val = val_r)

我试图获得第一步,select接近0的天数。但是,我失败了,很惨。 我用过这个:

data_b <- data %>%
  group_by(iid) %>% 
  which(abs(days-0)==min(abs(days-0)))
ungroup

我们只需要将 which 位置索引包装在 slice 中以对行进行子集化,然后执行 summarise

library(dplyr)
data %>%
   group_by(iid) %>% 
   slice( which(abs(days-0)==min(abs(days-0)))) %>%
   summarise(val = mean(val))

-输出

# A tibble: 4 x 2
  iid     val
  <chr> <dbl>
1 I1     41  
2 I2     34.8
3 I3     11  
4 I4     51.7

也可以写成

data %>%
     group_by(iid) %>% 
     slice_min(n = 1, order_by = abs(days)) %>%
     summarise(val = mean(val))

-输出

# A tibble: 4 x 2
  iid     val
  <chr> <dbl>
1 I1     41  
2 I2     34.8
3 I3     11  
4 I4     51.7

如果我们还需要 'days' 列,在 summarise 中(它可以灵活地扩展数据,因为它可以 return 每组多行),得到unique 'days' 还有

data %>%
     group_by(iid) %>% 
     slice_min(n = 1, order_by = abs(days)) %>%
     summarise(days = unique(days), val = mean(val), .groups = 'drop')

-输出

# A tibble: 6 x 3
  iid    days   val
  <chr> <dbl> <dbl>
1 I1        0  41  
2 I2       -1  34.8
3 I2        1  34.8
4 I3       -2  11  
5 I3        2  11  
6 I4        0  51.7