【发布时间】:2020-12-25 04:06:32
【问题描述】:
X Y
1 1 2
2 2 4
3 NA NA
4 NA NA
5 NA NA
6 NA NA
7 1 4
8 2 6
9 1 8
10 1 10
应该是这样:在第一种情况下,值 2 和 4 的平均值是 3 在第二种情况下,值 4、6、8、10 的平均值是 7,依此类推...
【问题讨论】:
X Y
1 1 2
2 2 4
3 NA NA
4 NA NA
5 NA NA
6 NA NA
7 1 4
8 2 6
9 1 8
10 1 10
应该是这样:在第一种情况下,值 2 和 4 的平均值是 3 在第二种情况下,值 4、6、8、10 的平均值是 7,依此类推...
【问题讨论】:
您的数据:
df = data.frame(X=c(1,2,NA,NA,NA,NA,1,2,1,1),Y=c(2,4,NA,NA,NA,NA,4,6,8,10))
您可以使用 diff(complete.cases(..)) 定义具有连续行且没有 NA 的行:
blocks = cumsum(c(0,diff(complete.cases(df)) != 0 ))
block_means = tapply(df$Y,blocks,mean)
0 1 2
3 NA 7
block_means[!is.na(block_means)]
0 2
3 7
或者如果您不需要知道顺序:
na.omit(as.numeric(tapply(df$Y,blocks,mean)))
[1] 3 7
【讨论】:
我们可以使用 data.table 中的 rleid 创建连续值组,在每个组内计算 mean 的 Y 值/
library(dplyr)
df %>%
group_by(gr = data.table::rleid(is.na(Y))) %>%
summarise(Y = mean(Y, na.rm = TRUE)) %>%
filter(!is.na(Y)) -> df1
df1
# gr Y
# <int> <dbl>
#1 1 3
#2 3 7
data.table 这样做的方式是:
library(data.table)
df1 <- setDT(df)[, .(Y = mean(Y, na.rm = TRUE)), rleid(is.na(Y))][!is.na(Y)]
数据
df <- structure(list(X = c(1L, 2L, NA, NA, NA, NA, 1L, 2L, 1L, 1L),
Y = c(2L, 4L, NA, NA, NA, NA, 4L, 6L, 8L, 10L)),
class = "data.frame", row.names = c(NA, -10L))
【讨论】:
select你想要的列。要选择gr 列,您可以执行df1 <- df %>% group_by(gr = data.table::rleid(is.na(Y))) %>% summarise(Y = mean(Y, na.rm = TRUE)) %>% filter(!is.na(Y)) %>% select(gr)。输出在df1。