【发布时间】:2020-08-25 13:52:04
【问题描述】:
一个数据框:
x <- c(3,4,8,10,NA,NA,NA,8,10,10,NA,22)
y <- c(1,6,3,5,NA,44,23,NA,NA,5,34,33)
df <- data.frame(x,y)
x y
<dbl> <dbl>
3 1
4 6
8 3
10 5
NA NA
NA 44
NA 23
8 NA
10 NA
10 5
NA 34
22 33
我想用两个最连续值的平均值替换 NA 值。例如 df[5,2] 是 NA 但我们可以将其替换为 5 和 44 的平均值:
df[5,2] <- (df[4,2]+df[6,2])/2
df[5,2]
[1] 24.5
但是,如果连续值也是NA,则无法完成此操作。用df[5,1] 和df[7,1] 之间的平均值替换df[6,1] 不起作用,因为它们也是NA。
我想要完成的是确保我用来计算平均值的值是最连续的两个,而不是NA。我创建了一个 for 循环来创建我们找到 NAs 的索引的数据框。然后我在NA 旁边创建了代表索引的变量,并进行了评估它们是否为NA 的测试。如果是TRUE,它们是 NA,则索引会根据相对于NA 索引的位置而增加或减少:
x <- as.data.frame(which(is.na(df), arr.ind = TRUE))
str(x)
'data.frame': 7 obs. of 2 variables:
$ row: int 5 6 7 11 5 8 9
$ col: int 1 1 1 1 2 2 2
您将看到一个数据框,其中包含NAs 在数据集中的位置的行值和列值。现在我尝试覆盖它们:
for (i in 1:dim(x)[1]) {
row <- x[i,1] # First for loop assigns row and column values using the location of NA
col <- x[i,2]
b <- row - 1 # Create a list of the indices that precede the NA
a <- row + 1 # Create a list of the indices that go after the NA
ifelse(is.na(df[b[i],col]), b[i]-1, b[i]) # If the value in the list is also an NA, keep looking
ifelse(is.na(df[a[i],col]), a[i]+1, a[i])
df[row,col] <- (df[b,col]+df[a,col])/2 # Replace the NA with the mean of values where we could
# find integers
}
唉,我无法通过所有的 NA。我还没有想出更好的解决方案,因此转向更好的头脑。非常感谢!
y <- as.data.frame(which(is.na(df), arr.ind = TRUE))
str(y)
'data.frame': 5 obs. of 2 variables:
$ row: int 5 6 7 8 9
$ col: int 1 1 1 2 2
【问题讨论】:
-
为了确保我理解您的问题,
df$x中的第五、第六和第七个值(第一列中的三个连续的NA值)都应该是 9 ( (10+8 )/2 ),对吗? -
@duckmayr 你是对的。