我有一个数据帧,我需要为每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
感谢您的帮助!
答案 0 :(得分:3)
我们可以使用row_number
功能,同时也使用group_by
来提供解决方案:
我们首先创建一个名为row_num_mod
的变量,它接受row_number mod 3
。然后,我们可以按row_num_mod
和Name
进行分组,找出观察所属的实例。
我们可以再次使用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