我在这里提供了两个向量:
vec1 <- c(5, 2, 2, 2, 2, 3, 2, 3, 9, 6, 2, 2, 2, 3)
vec2 <- c(1.96845698, 1.11342534, 0.82580110, 0.35762122, 0.07210485, 0.06046759, 0.93615974, 0.85691566, 0.39439991,
0.26110080, 1.22082336, 0.71940824, 0.32571803, 0.46358160, 0.16009616, 0.13348428, 1.16801097, 0.30184661,
0.51190796, 1.69680701, 0.54418158, 0.74969466, 0.17246107, 0.66953561, 1.02689205, 1.67408220, 1.20311478,
0.74049935, 0.55211334, 0.31037724, 0.23620425, 0.34532764, 1.64696898, 0.23094382, 0.67733098, 0.32226374,
0.25774802, 0.35768477, 0.27219803, 0.02042260, 0.53784081, 1.27521977, 0.07043151, 0.11879638, 0.13358880)
现在我想计算vec2
中不同部分的平均值。这些部分的长度由vec1
的值决定。
因此输出应该是与vec1
长度相同的向量。
这个输出向量的第一个值应该是vec2[1:5]
的mean
,因为vec1[1] = 5
。第二个值应该vec[6:7]
mean
,自从vec[2] = 2
等等,直到最后一个值的输出向量应该对应于mean
vec2[43:45]
,自从上次的价值vec1
3
。
我希望你明白我的意思。
这里我手动计算期望的输出向量:
vec3 <- c(0.8674819, 0.4983137, 0.6256578, 0.7409621, 0.5225631, 0.2523873, 0.7349288,
0.9176322, 0.7887523, 0.5765066, 0.3077164, 0.1463103, 0.9065303, 0.1076056)
有人知道怎么做吗?
您可以尝试:
tapply(vec2, rep(seq_along(vec1), vec1), mean)
#tapply(vec2, unlist(Map(rep, seq_along(vec1), each=vec1)), mean) #Alternative
#tapply(vec2, inverse.rle(list(lengths=vec1, values=seq_along(vec1))), mean) #Alternative
# 1 2 3 4 5 6 7 8
#0.8674819 0.4983137 0.6256578 0.7409621 0.5225631 0.2523873 0.7349288 0.9176322
# 9 10 11 12 13 14
#0.7887523 0.5765066 0.3077164 0.1463103 0.9065303 0.1076056
如果您稍微重新排列vec1
,则可以使用聚合函数来完成此操作:
vec1 <- rep(seq_along(vec1), vec1)
aggregate(vec2, list(vec1), mean)$x
# [1] 0.8674819 0.4983137 0.6256578 0.7409621 0.5225631 0.2523873 0.7349288 0.9176322 0.7887523 0.5765066 0.3077164 0.1463103 0.9065303 0.1076056
另一个使用purrr的解决方案
# first construct the ranges which is used as input in the purrr-call
range2 <- cumsum(vec1)
range1 <- c(1,cumsum(vec1[1:(length(vec1)-1)])+1)
purrr::map2_dbl(range1, range2, function(x,y) mean(vec2[x:y]))
[1] 0.8674819 0.4983137 0.6256578 0.7409621 0.5225631 0.2523873 0.7349288 0.9176322 0.7887523 0.5765066 0.3077164 0.1463103 0.9065303 0.1076056
还有一个选项是:
tapply(vec2, cumsum(sequence(vec1) == 1), mean)
1 2 3 4 5 6 7 8 9
0.8674819 0.4983137 0.6256578 0.7409621 0.5225631 0.2523873 0.7349288 0.9176322 0.7887523
10 11 12 13 14
0.5765066 0.3077164 0.1463103 0.9065303 0.1076056
使用tidyverse
library(dplyr)
library(tidyr)
tibble(vec1) %>%
mutate(grp = row_number()) %>%
uncount(vec1) %>%
mutate(vec2 = vec2) %>%
group_by(grp) %>%
summarise(vec2 = mean(vec2))
# A tibble: 14 × 2
grp vec2
<int> <dbl>
1 1 0.867
2 2 0.498
3 3 0.626
4 4 0.741
5 5 0.523
6 6 0.252
7 7 0.735
8 8 0.918
9 9 0.789
10 10 0.577
11 11 0.308
12 12 0.146
13 13 0.907
14 14 0.108