通过取2x2的空间平均值,将8x8的数据框缩小为4x4。

3
假设我有一个数据框,其中每个观测值表示二维空间中特定点上的给定变量:
data = data.frame(col1 = c(1,2,3,4,5,6,7,8), col2 = c(2,3,'NA',5,6,7,8,9), col3 = c(3,4,5,6,7,8,9,10), col4 = c(2,3,4,1,2,6,7,8),
                  col5 = c(2,3,'NA','NA',6,7,8,9), col6 = c(1,2,3,5,6,7,8,9), col7 = c(1,2,3,4,6,7,'NA','NA'), col8 = c(1,2,3,4,5,6,'NA','NA'))

> print(data)
  col1 col2 col3 col4 col5 col6 col7 col8
1    1    2    3    2    2    1    1    1
2    2    3    4    3    3    2    2    2
3    3   NA    5    4   NA    3    3    3
4    4    5    6    1   NA    5    4    4
5    5    6    7    2    6    6    6    5
6    6    7    8    6    7    7    7    6
7    7    8    9    7    8    8   NA   NA
8    8    9   10    8    9    9   NA   NA

该数据框为 8x8(8 列 8 行),总共有 36 个观测值。

我需要通过将每个 2x2 观测值组的平均值来将其缩小为 4x4 数据框。

2x2 的 NAs 组应返回一个NA值,而如果在 2x2 组内存在 < 4 个 NAs,则平均值必须排除它们,例如 2,2,2,NA 的平均值为 2。

这里是我的期望输出:

newcol1  newcol2  newcol3  newcol4
   2        3        2       1.50
   4        4        4       3.50
   6       5.75     6.50      6
   8       8.50     8.50      NA

我认为可以用for循环解决这个问题,以下是我的尝试但没有成功:

a = 1
b = 2

for (i in 1:15) {
      test[[i]] = mean(c(data[a,a], data[a,b], data[b,a], data[b,b]))
      test[[i]] = mean(c(data[a+i,a+i], data[a+i,b+i], data[b+i,a+i], data[b+i,b+i]))
}

我在网上搜索了很多,但找不到类似的问题或解决方案。

有什么建议吗?

是否有可以进行此类空间分析的R包?

2个回答

3

从链接的帖子中,使用@flodel的答案,将sum替换为mean

a <- as.matrix(data)

#convert matrix from char to num, ignore warnings, they are due to NAs
class(a) <- "numeric" 

#adapted from @flodel https://dev59.com/_nLYa4cB1Zd3GeqPcNWY#16884987/680068
res <- tapply(a, list((row(a) + 1L) %/% 2L, (col(a) + 1L) %/% 2L), mean, na.rm = TRUE)

# remove NANs
res[ is.nan(res) ] <- NA
res
#   1    2   3   4
# 1 2 3.00 2.0 1.5
# 2 4 4.00 4.0 3.5
# 3 6 5.75 6.5 6.0
# 4 8 8.50 8.5  NA

1
这对我来说只给出了NA值。为了使这种方法起作用,我必须将矩阵中的值转换为数值。 - Johannes Ranke

1
这是一种愚笨的解决方案(不是非常通用),但适用于有限的示例。我想还有更聪明的方法。
R8toR4 <- function(mat) {
  stopifnot(identical(dim(mat), c(8L, 8L)))

  out <- matrix(nrow = 4, ncol = 4)

  for (i in 1:nrow(out)) {
    for (j in 1:ncol(out)) {
      submatrix <- mat[i * 2 - c(1, 0), j * 2 - c(1, 0)]
      if (all(is.na(submatrix))) {
        out[i, j] <- NA
      } else {
        out[i, j] <- mean(submatrix, na.rm = TRUE)
      }
    }
  }

  out
}


DataMatrix <- as.matrix(data)
R8toR4(DataMatrix)
     [,1] [,2] [,3] [,4]
[1,]    2 3.00  2.0  1.5
[2,]    4 4.00  4.0  3.5
[3,]    6 5.75  6.5  6.0
[4,]    8 8.50  8.5   NA

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接