基于条件的 Rollmean
Rollmean based on conditions
基于下面的数据框,我想根据三个条件使用 rollmean 创建一个新列 - b 列中的值相互匹配,a 列中要平均的最小值为 2,我只想要对当前行下方的所有值进行平均。如果要平均的值的数量是 2 或更少,我想 return 一个空白值。
我假设我必须使用应用函数来执行此操作,但我不确定从哪里开始。
a=c(1,2,3,4,1,2,3,4,1,2,3,4)
b=c("X","X","X","X","Y","Y","Y","Y","Z","Z","Z","Z")
df=as.data.frame(cbind(a,b))
我希望最后的 table 看起来像:
Name Value Output
X 1 2.5
X 2 3
X 3
X 4
Y 1 2.5
Y 2 3
Y 3
Y 4
Z 1 2.5
Z 2 3
Z 3
Z 4
一个简单的tidverse
解决方案。在每个组中,如果还剩两个以上的项目,则取当前索引 (row_number()
) 到最终索引 (n()
) 的平均值。
library(tidyverse)
df %>%
group_by(b) %>%
mutate(Output = map_dbl(row_number(), ~ifelse(n() - . < 3, NA, mean(a[.:n()]))))
数据
您创建数据的方式将 b
强制转换为字符向量(因为 cbind
构成了一个矩阵)。
简单使用:
a <- c(1,2,3,4,1,2,3,4,1,2,3,4)
b <- c("X","X","X","X","Y","Y","Y","Y","Z","Z","Z","Z")
df <- data.frame(a, b)
或
df <- data.frame(a = 1:4, b = rep(c('X', 'Y', 'Z'), each = 4))
注意问题中df
的格式有误所以我们在下面修改了。我们可以这样使用 ave
。没有使用包。
df <- data.frame(a, b)
fun <- function(x) if (length(x) <= 2) NA else rev(cumsum(rev(x)) / c(NA, NA, 3:length(x)))
transform(df, Output = ave(a, b, FUN = fun))
给予:
a b Output
1 1 X 2.5
2 2 X 3.0
3 3 X NA
4 4 X NA
5 1 Y 2.5
6 2 Y 3.0
7 3 Y NA
8 4 Y NA
9 1 Z 2.5
10 2 Z 3.0
11 3 Z NA
12 4 Z NA
基于下面的数据框,我想根据三个条件使用 rollmean 创建一个新列 - b 列中的值相互匹配,a 列中要平均的最小值为 2,我只想要对当前行下方的所有值进行平均。如果要平均的值的数量是 2 或更少,我想 return 一个空白值。
我假设我必须使用应用函数来执行此操作,但我不确定从哪里开始。
a=c(1,2,3,4,1,2,3,4,1,2,3,4)
b=c("X","X","X","X","Y","Y","Y","Y","Z","Z","Z","Z")
df=as.data.frame(cbind(a,b))
我希望最后的 table 看起来像:
Name Value Output
X 1 2.5
X 2 3
X 3
X 4
Y 1 2.5
Y 2 3
Y 3
Y 4
Z 1 2.5
Z 2 3
Z 3
Z 4
一个简单的tidverse
解决方案。在每个组中,如果还剩两个以上的项目,则取当前索引 (row_number()
) 到最终索引 (n()
) 的平均值。
library(tidyverse)
df %>%
group_by(b) %>%
mutate(Output = map_dbl(row_number(), ~ifelse(n() - . < 3, NA, mean(a[.:n()]))))
数据
您创建数据的方式将 b
强制转换为字符向量(因为 cbind
构成了一个矩阵)。
简单使用:
a <- c(1,2,3,4,1,2,3,4,1,2,3,4)
b <- c("X","X","X","X","Y","Y","Y","Y","Z","Z","Z","Z")
df <- data.frame(a, b)
或
df <- data.frame(a = 1:4, b = rep(c('X', 'Y', 'Z'), each = 4))
注意问题中df
的格式有误所以我们在下面修改了。我们可以这样使用 ave
。没有使用包。
df <- data.frame(a, b)
fun <- function(x) if (length(x) <= 2) NA else rev(cumsum(rev(x)) / c(NA, NA, 3:length(x)))
transform(df, Output = ave(a, b, FUN = fun))
给予:
a b Output
1 1 X 2.5
2 2 X 3.0
3 3 X NA
4 4 X NA
5 1 Y 2.5
6 2 Y 3.0
7 3 Y NA
8 4 Y NA
9 1 Z 2.5
10 2 Z 3.0
11 3 Z NA
12 4 Z NA