计算按因子水平分组的有限范围数值变量的均值
Compute means of limited range of numeric variable grouped by factor levels
我有一个数据框,其中包含一个数值变量 V1
和一个因子变量 Effect
:
set.seed(123)
df <- data.frame(
V1 = c(rnorm(100)),
Effect = sample(LETTERS[1:4], 100, replace = T)
)
对于每个 Effect
级别,我想计算 V1
的那些值在第一和第三四分位数之间的均值。我知道如何计算所有因子水平的四分位数:
quants <- aggregate(V1 ~ Effect, data = df, quantile)
quants
Effect V1.0% V1.25% V1.50% V1.75% V1.100%
1 A -2.30916888 -0.55815839 -0.02854676 0.55115731 1.53261063
2 B -1.96661716 -0.37066003 0.33178196 0.68864025 1.36860228
3 C -1.13813694 -0.42358228 0.01381897 0.92773709 2.16895597
4 D -1.02642090 -0.49385424 -0.22407620 0.72100821 2.18733299
但现在我正在努力研究如何使用 quants
中的信息一次性计算所有因子水平的相关均值。
到目前为止我已经试过了:
我已经转换 quants
以使其更易于访问:
quants <- as.data.frame.list(quants)
然后我使用了这个tapply
语句:
tapply(df$V1, df$Effect, function(x) mean(x[x >= quants_new$V1.25. & x <= quants_new$V1.75.]))
但是结果不正确,并且有警告:
A B C D
0.172908276 0.167233413 0.002957323 -0.108590409
Warning messages:
1: In x >= quants_new$V1.25. :
longer object length is not a multiple of shorter object length
2: In x <= quants_new$V1.75. :
longer object length is not a multiple of shorter object length
3: In x >= quants_new$V1.25. :
longer object length is not a multiple of shorter object length
4: In x <= quants_new$V1.75. :
longer object length is not a multiple of shorter object length
如何固定 tapply
语句来计算所有因子水平限制在四分位数范围内的均值?也欢迎其他解决方案。
我没有检查数字是否正确,但是使用 data.table 包中的 data.table()
而不是 data.frame,应该可以满足我的需求之后...
dt1[V1 > quantile(V1, 0.25) & V1 < quantile(V1, 0.75),
mean(V1), keyby = Effect]
这是按 "Effect" 对您的数据进行分组,在这些组中取中间 50% 的值,并取这些值的平均值。
编辑,上面的代码在分组之前先取子集(抱歉,我的测试没有做到这一点)以获取每个组的分位数:
dt1[dcast(dt1[, .(unlist(lapply(.SD, quantile, c(0.25, 0.75))), qt = c("lo", "up")), by = Effect], ... ~ qt, value.var = "V1"), on = "Effect"][V1 >= lo & V1 <= up, mean(V1), keyby = Effect]
这提供了与 Ronak 的答案相同的值。它获取每个组的分位数,dcast
扩大它,将其加入原始 data.table,然后使用新变量 lo 和 up(下分位数和上分位数边界)进行子集化并取每组的平均值剩余的值。
我们可以在 aggregate
内部做到这一点:
aggregate(V1~Effect, df, function(x)
mean(x[x >= quantile(x, 0.25) & x <= quantile(x, 0.75)], na.rm = TRUE))
使用 dplyr
可能是:
library(dplyr)
df %>%
group_by(Effect) %>%
summarise(mean_val = mean(V1[between(V1, quantile(V1, 0.25),
quantile(V1, 0.75))], na.rm = TRUE))
我有一个数据框,其中包含一个数值变量 V1
和一个因子变量 Effect
:
set.seed(123)
df <- data.frame(
V1 = c(rnorm(100)),
Effect = sample(LETTERS[1:4], 100, replace = T)
)
对于每个 Effect
级别,我想计算 V1
的那些值在第一和第三四分位数之间的均值。我知道如何计算所有因子水平的四分位数:
quants <- aggregate(V1 ~ Effect, data = df, quantile)
quants
Effect V1.0% V1.25% V1.50% V1.75% V1.100%
1 A -2.30916888 -0.55815839 -0.02854676 0.55115731 1.53261063
2 B -1.96661716 -0.37066003 0.33178196 0.68864025 1.36860228
3 C -1.13813694 -0.42358228 0.01381897 0.92773709 2.16895597
4 D -1.02642090 -0.49385424 -0.22407620 0.72100821 2.18733299
但现在我正在努力研究如何使用 quants
中的信息一次性计算所有因子水平的相关均值。
到目前为止我已经试过了:
我已经转换 quants
以使其更易于访问:
quants <- as.data.frame.list(quants)
然后我使用了这个tapply
语句:
tapply(df$V1, df$Effect, function(x) mean(x[x >= quants_new$V1.25. & x <= quants_new$V1.75.]))
但是结果不正确,并且有警告:
A B C D
0.172908276 0.167233413 0.002957323 -0.108590409
Warning messages:
1: In x >= quants_new$V1.25. :
longer object length is not a multiple of shorter object length
2: In x <= quants_new$V1.75. :
longer object length is not a multiple of shorter object length
3: In x >= quants_new$V1.25. :
longer object length is not a multiple of shorter object length
4: In x <= quants_new$V1.75. :
longer object length is not a multiple of shorter object length
如何固定 tapply
语句来计算所有因子水平限制在四分位数范围内的均值?也欢迎其他解决方案。
我没有检查数字是否正确,但是使用 data.table 包中的 data.table()
而不是 data.frame,应该可以满足我的需求之后...
dt1[V1 > quantile(V1, 0.25) & V1 < quantile(V1, 0.75),
mean(V1), keyby = Effect]
这是按 "Effect" 对您的数据进行分组,在这些组中取中间 50% 的值,并取这些值的平均值。
编辑,上面的代码在分组之前先取子集(抱歉,我的测试没有做到这一点)以获取每个组的分位数:
dt1[dcast(dt1[, .(unlist(lapply(.SD, quantile, c(0.25, 0.75))), qt = c("lo", "up")), by = Effect], ... ~ qt, value.var = "V1"), on = "Effect"][V1 >= lo & V1 <= up, mean(V1), keyby = Effect]
这提供了与 Ronak 的答案相同的值。它获取每个组的分位数,dcast
扩大它,将其加入原始 data.table,然后使用新变量 lo 和 up(下分位数和上分位数边界)进行子集化并取每组的平均值剩余的值。
我们可以在 aggregate
内部做到这一点:
aggregate(V1~Effect, df, function(x)
mean(x[x >= quantile(x, 0.25) & x <= quantile(x, 0.75)], na.rm = TRUE))
使用 dplyr
可能是:
library(dplyr)
df %>%
group_by(Effect) %>%
summarise(mean_val = mean(V1[between(V1, quantile(V1, 0.25),
quantile(V1, 0.75))], na.rm = TRUE))