R语言中拆分向量后按段位置填充均值与NA的实现问题
我来帮你搞定这个问题!你的需求是把一个向量拆分成s个部分,计算每个部分的均值后,生成一个和原向量长度相同的新向量,仅在每个分组的指定位置放置均值,其余位置填充NA。咱们先看看原代码的问题,再给出正确的实现。
原代码的问题
你的原代码中,最后一步用seq(from = 1 , to = length(vec), length = length(res))生成的是从向量开头到结尾均匀分布的s个位置,比如当s=2、向量长度为8时,这个序列是1和8,所以均值被放到了第1位和第8位,这和你期望的位置不符。
正确实现方案
我们需要先确定每个分组的目标位置(比如每个分组的第一个元素位置),再将均值填充到对应位置。下面分两种常见的分组方式给出代码:
方式1:循环分组(和原代码的分组逻辑一致)
这种方式是将向量元素按顺序循环分配到s个组中(比如s=2时,第1、3、5、7个元素为一组,第2、4、6、8个为另一组),然后将每个组的均值放到该组的第一个元素位置:
vec <- c(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000) s <- 2 # 生成循环分组索引 group_idx <- rep(1:s, ceiling(length(vec)/s), length.out = length(vec)) # 拆分向量为分组 parts <- split(vec, group_idx) # 计算每个分组的均值 group_means <- sapply(parts, mean) # 获取每个分组的第一个元素在原向量中的位置(更可靠的方式) positions <- sapply(1:s, function(g) min(which(group_idx == g))) # 初始化全NA的结果向量 res <- rep(NA, length(vec)) # 将均值填充到对应位置 res[positions] <- group_means res
运行结果:4000 5000 NA NA NA NA NA NA
如果你的目标位置不是第一个元素,而是其他位置(比如s=2时想放到第1和第4位),只需要调整positions的生成逻辑即可。比如要取每个分组的第2个元素位置:
positions <- sapply(1:s, function(g) which(group_idx == g)[2]) res[positions] <- group_means
此时结果:NA NA 4000 5000 NA NA NA NA
方式2:连续分段分组
如果你想把向量拆分成s个连续的段(比如s=2时,前4个元素为一组,后4个为另一组),代码如下:
vec <- c(1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000) s <- 2 # 生成连续分段的分组索引 group_idx <- cut(1:length(vec), breaks = s, labels = 1:s) parts <- split(vec, group_idx) group_means <- sapply(parts, mean) # 获取每个分段的起始位置 positions <- sapply(parts, function(x) match(x[1], vec)) res <- rep(NA, length(vec)) res[positions] <- group_means res
运行结果:2500 NA NA NA 6500 NA NA NA
针对你给出的期望结果调整
如果你需要完全匹配你给出的s=2和s=3的期望结果,我们可以手动指定位置(不过看起来你的期望位置和分组逻辑的对应关系有些模糊,建议先确认分组和目标位置的规则):
比如s=3时,按你期望的位置1、5、8填充:
s <- 3 group_idx <- rep(1:s, ceiling(length(vec)/s), length.out = length(vec)) parts <- split(vec, group_idx) group_means <- sapply(parts, mean) # 手动指定位置 positions <- c(1,5,8) res <- rep(NA, length(vec)) res[positions] <- group_means res
运行结果:4000 NA NA NA 5000 NA NA 4500,和你给出的期望结果一致。
内容的提问来源于stack exchange,提问作者George

