从数据框的某些特定单元格中删除 "NA"。不是所有的人

Remove "NA" from some specific cells of a data frame. Not all of them

所以我的数据格式如下:

    A   B   C   D   E   F
1   12  NA  NA  28  NA  NA
2   34  NA  NA  29  NA  34
3   98  98  NA  90  NA  67
4   29  34  84  NA  NA  67
5   84  NA  29  89  NA  45
6   87  76  28  28  34  67
7   87  23  28  20  24  34
8   32  98  28  49  23  67
9   43  43  27  39  56  30
10  93  23  85  90  46  65

现在我想要以下格式:

    A   B   C   D   E   F
1   12  98  84  28  34  34
2   34  34  29  29  24  67
3   98  NA  28  90  23  67
4   29  76  28  NA  56  45
5   84  23  28  89  46  67
6   87  98  27  28      34
7   87  43  85  20      67
8   32  23      49      30
9   43          39      65
10  93          90      

然后我想用该列的中位数填充 NA 的左侧。

任何人都可以帮助我。我是 R 的新手,对如何实现这一目标感到困惑。

提前致谢。

这只能使用基础 R 来完成。

我将使用名为 dat1dat2 的数据副本。前者会将所有非缺失值的中位数归因于缺失值。后者将在计算中位数之前从向量中删除顶部和底部值。

dat1 <- dat2 <- dat    # Make two copies of the data

dat1[] <- lapply(dat, function(x){
  if(anyNA(x)){
    inx <- which(is.na(x))
    x[inx] <- median(x, na.rm = TRUE)
    c(x[-inx], x[inx])
  } else x
})

dat2[] <- lapply(dat, function(x){
  if(anyNA(x)){
    inx <- which(is.na(x))
    x_tmp <- x[-inx]
    x[inx] <- median(x_tmp[-c(1, length(x_tmp))], na.rm = TRUE)
    c(x[-inx], x[inx])
  } else x
})

dat1
#    A  B  C  D  E  F
#1  12 98 84 28 34 34
#2  34 34 29 29 24 67
#3  98 76 28 90 23 67
#4  29 23 28 89 56 45
#5  84 98 28 28 46 67
#6  87 43 27 20 34 34
#7  87 23 85 49 34 67
#8  32 43 28 39 34 30
#9  43 43 28 90 34 65
#10 93 43 28 39 34 65

dat2
#   A  B  C  D  E  F
#1  12 98 84 28 34 34
#2  34 34 29 29 24 67
#3  98 76 28 90 23 67
#4  29 23 28 89 56 45
#5  84 98 28 28 46 67
#6  87 43 27 20 24 34
#7  87 23 85 49 24 67
#8  32 43 28 39 24 30
#9  43 43 28 90 24 65
#10 93 43 28 39 24 67

编辑。

以下函数执行上述两个匿名函数的操作。所需要做的就是将参数设置为适当的值。

请注意,测试结果与上面的原始结果进行了比较。

imputeStat <- function(x, stat = median, remove = c("top", "bottom")){
  if(anyNA(x)){
    inx <- which(is.na(x))
    x_tmp <- x[-inx]
    if("top" %in% remove) inx_rem <- 1
    if("bottom" %in% remove) inx_rem <- c(inx_rem, length(x[-inx]))
    if(is.logical(remove)){
      if(!remove) x[inx] <- median(x, na.rm = TRUE)
    }else{
      x[inx] <- median(x_tmp[-inx_rem], na.rm = TRUE)
    }
    c(x[-inx], x[inx])
  } else x
}

dat3 <- dat
dat3[] <- lapply(dat3, imputeStat, remove = FALSE)
identical(dat1, dat3)
#[1] TRUE

dat4 <- dat
dat4[] <- lapply(dat4, imputeStat)
identical(dat2, dat4)
#[1] TRUE

数据.

dat <- read.table(text = "
    A   B   C   D   E   F
1   12  NA  NA  28  NA  NA
2   34  NA  NA  29  NA  34
3   98  98  NA  90  NA  67
4   29  34  84  NA  NA  67
5   84  NA  29  89  NA  45
6   87  76  28  28  34  67
7   87  23  28  20  24  34
8   32  98  28  49  23  67
9   43  43  27  39  56  30
10  93  23  85  90  46  65
", header = TRUE)