用 R 中的最后一个非空单元格和下一个非空单元格填充列中两个值之间的空单元格
Fill empty cells between two values in column with last non empty cell and next non empty cell in R
我需要遍历数据帧中的 ID,通过在 NA 单元格之外的最后一个和第一个填充条目之间均匀分配空单元格来填充列中的 NA 值。
ID Value X Y
1 A x y
1 NA x y
1 NA x y
1 NA x y
1 NA x y
1 NA x y
1 B x y
2 C x y
2 NA x y
2 NA x y
2 NA x y
2 NA x y
2 D x y
应该填到这个:
ID Value X Y
1 A x y
1 A x y
1 A x y
1 B x y
1 B x y
1 B x y
1 B x y
2 C x y
2 C x y
2 C x y
2 D x y
2 D x y
2 D x y
如果 2n 观察值之间的 NA 值,n 归因于最后一个 n 到下一个。在 2n+1 值的情况下,n 归因于最后一个,而 n+1 归因于最后一个接下来。
我知道我需要使用 zoo
包中的 na.locf
,它可以很好地与大型数据库配合使用,以根据最后一个非空单元格以及 fromLast
执行“下一次观察向后进行”的参数。但是,我无法构建一个循环来说明偶数或奇数个 NA 值,并将这两个值一起使用。
使用 tidyverse 包,
> library(tidyr)
> library(dplyr)
> df %>% dplyr::group_by(test$id) %>% fill(Value, .direction ="downup") %>% dplyr::ungroup()
这会在两个方向上填充 NA 值,但不会考虑组中 NA 单元格的不同边界值。
定义 interp,它用连续的整数替换每个连续的非 NA,应用 na.appro9x,舍入并用原始值替换结果整数。
library(zoo)
interp <- function(x) {
x0 <- ifelse(is.na(x), NA, cumsum(!is.na(x)))
xx <- na.approx(x0, rule = 2)
na.omit(x)[round(xx)]
}
transform(DF, Value = interp(Value))
给予:
ID Value X Y
1 1 A x y
2 1 A x y
3 1 A x y
4 1 B x y
5 1 B x y
6 1 B x y
7 1 B x y
8 2 C x y
9 2 C x y
10 2 C x y
11 2 D x y
12 2 D x y
13 2 D x y
备注
假设输入如下,以可重现的形式显示。
Lines <- "ID Value X Y
1 A x y
1 NA x y
1 NA x y
1 NA x y
1 NA x y
1 NA x y
1 B x y
2 C x y
2 NA x y
2 NA x y
2 NA x y
2 NA x y
2 D x y"
DF <- read.table(text = Lines, header = TRUE)
我想最简单的方法是使用函数:na.locf:如果我们在 zoo/time-series.
,则上次观察结转
参见:https://www.rdocumentation.org/packages/zoo/versions/1.8-9/topics/na.locf
我需要遍历数据帧中的 ID,通过在 NA 单元格之外的最后一个和第一个填充条目之间均匀分配空单元格来填充列中的 NA 值。
ID Value X Y
1 A x y
1 NA x y
1 NA x y
1 NA x y
1 NA x y
1 NA x y
1 B x y
2 C x y
2 NA x y
2 NA x y
2 NA x y
2 NA x y
2 D x y
应该填到这个:
ID Value X Y
1 A x y
1 A x y
1 A x y
1 B x y
1 B x y
1 B x y
1 B x y
2 C x y
2 C x y
2 C x y
2 D x y
2 D x y
2 D x y
如果 2n 观察值之间的 NA 值,n 归因于最后一个 n 到下一个。在 2n+1 值的情况下,n 归因于最后一个,而 n+1 归因于最后一个接下来。
我知道我需要使用 zoo
包中的 na.locf
,它可以很好地与大型数据库配合使用,以根据最后一个非空单元格以及 fromLast
执行“下一次观察向后进行”的参数。但是,我无法构建一个循环来说明偶数或奇数个 NA 值,并将这两个值一起使用。
使用 tidyverse 包,
> library(tidyr)
> library(dplyr)
> df %>% dplyr::group_by(test$id) %>% fill(Value, .direction ="downup") %>% dplyr::ungroup()
这会在两个方向上填充 NA 值,但不会考虑组中 NA 单元格的不同边界值。
定义 interp,它用连续的整数替换每个连续的非 NA,应用 na.appro9x,舍入并用原始值替换结果整数。
library(zoo)
interp <- function(x) {
x0 <- ifelse(is.na(x), NA, cumsum(!is.na(x)))
xx <- na.approx(x0, rule = 2)
na.omit(x)[round(xx)]
}
transform(DF, Value = interp(Value))
给予:
ID Value X Y
1 1 A x y
2 1 A x y
3 1 A x y
4 1 B x y
5 1 B x y
6 1 B x y
7 1 B x y
8 2 C x y
9 2 C x y
10 2 C x y
11 2 D x y
12 2 D x y
13 2 D x y
备注
假设输入如下,以可重现的形式显示。
Lines <- "ID Value X Y
1 A x y
1 NA x y
1 NA x y
1 NA x y
1 NA x y
1 NA x y
1 B x y
2 C x y
2 NA x y
2 NA x y
2 NA x y
2 NA x y
2 D x y"
DF <- read.table(text = Lines, header = TRUE)
我想最简单的方法是使用函数:na.locf:如果我们在 zoo/time-series.
,则上次观察结转参见:https://www.rdocumentation.org/packages/zoo/versions/1.8-9/topics/na.locf