通过对r中的另一列进行分组来表示n行的平均值

时间:2017-03-20 17:31:52

标签: r group-by aggregate mean

我有一个数据帧,我需要为每n行计算x的平均值 通过分组名称,假设n = 3
样本数据集df:

 Name     X  
  A      3.1     
  A      2.5    
  A      3.6  
  A      3.4  
  B      4.6  
  B      1.8  
  B      3.4 

对于每个名称,前3行的平均值,然后是下3行,
 如果最终<名称为3行,表示1行或2行。

到目前为止,我已经能够分别为3行或名字分组 如何将这两者结合在一起的任何帮助将不胜感激。

## by grouping 3 rows##
final1<-aggregate(df$X,list(rep(1(nrow(df)%/%n+1),each=n,len=nrow(df))),mean)[-1]  

##by grouping name##
final2<- df %>% group_by(Name) %>% summarise(value=mean(df$X))  

所需的输出是:

  Name      X     
   A      3.066  
   A      3.400  
   B      3.266  

感谢您的帮助!

4 个答案:

答案 0 :(得分:3)

我们可以使用row_number功能,同时也使用group_by来提供解决方案:

我们首先创建一个名为row_num_mod的变量,它接受row_number mod 3。然后,我们可以按row_num_modName进行分组,找出观察所属的实例。

我们可以再次使用row_number,以便我们基本上对不同的值mod 3进行排序。

dat %>%
    group_by(Name) %>%
    mutate(row_num_mod = row_number() %% 3) %>% 
    ungroup() %>%
    group_by(row_num_mod, Name) %>%
    mutate(row_num2 = row_number()) %>% # which instance of x mod 3 is this?
    ungroup() %>%
    group_by(Name, row_num2) %>%
    summarise(Mean = mean(X))

   Name row_num2     Mean
  <chr>    <int>    <dbl>
1     A        1 3.066667
2     A        2 3.400000
3     B        1 3.266667

净度

为了演示我们添加的字段,以下是添加row_num2后的数据:

   Name     X row_num_mod row_num2
  <chr> <dbl>       <dbl>    <int>
1     A   3.1           1        1
2     A   2.5           2        1
3     A   3.6           0        1
4     A   3.4           1        2
5     B   4.6           1        1
6     B   1.8           2        1
7     B   3.4           0        1

数据

dat <- read.table(text = " Name     X  
  A      3.1     
  A      2.5    
  A      3.6  
  A      3.4  
  B      4.6  
  B      1.8  
  B      3.4 ", header = TRUE, stringsAsFactors = FALSE)

答案 1 :(得分:1)

另一种方法是使用%/%n()代替%%row_number

dat %>% 
  group_by(Name) %>% 
  mutate(ind = 0:(n() - 1) %/% 3) %>% 
  group_by(ind, add = TRUE) %>% 
  summarise(Mean = mean(X))
## Source: local data frame [3 x 3]
## Groups: Name [?]
## 
##    Name   ind     Mean
##   <chr> <dbl>    <dbl>
## 1     A     0 3.066667
## 2     A     1 3.400000
## 3     B     0 3.266667

答案 2 :(得分:0)

使用zoo包中的rollapply。我们可以使用by = 3参数以3为步长移动滚动窗口,我们可以使用partial = TRUE来包含小于3的组,这些组最后会留下。我在这里演示了使用data.table进行分组,尽管你也可以使用dplyr或base函数进行分组:

dt[, rollapply(X, 3, mean, by = 3, align = "left", partial=T), by=Name]
#    Name       V1
# 1:    A 3.066667
# 2:    A 3.400000
# 3:    B 3.266667

数据和库:

library(data.table)
library(zoo)
dt= fread ("Name     X  
A      3.1     
A      2.5    
A      3.6  
A      3.4  
B      4.6  
B      1.8  
B      3.4 ")

答案 3 :(得分:0)

以下是data.table的另一种解决方案:

library("data.table")
dt <- fread(
' Name     X  
  A      3.1     
  A      2.5    
  A      3.6  
  A      3.4  
  B      4.6  
  B      1.8  
  B      3.4 ')
dt[, n3:=gl(.N, 3, length=.N), by=Name]
dt[, .(X=mean(X)), by=.(Name, n3)]
# > dt[, .(X=mean(X)), by=.(Name, n3)]
#    Name n3        X
# 1:    A  1 3.066667
# 2:    A  2 3.400000
# 3:    B  1 3.266667