【问题标题】:Identify NA's in sequence row-wise按行顺序识别 NA
【发布时间】:2016-12-16 22:24:59
【问题描述】:

我想根据条件按行填充序列中的 NA 值。请看下面的例子。

ID | Observation 1 | Observation 2 | Observation 3 | Observation 4 | Observation 5
 A         NA              0               1             NA             NA

条件是:

  • 序列中 !NA 值之前的所有 NA 值应保留为 NA;
  • 但序列中 !NA 值之后的所有 NA 都应标记(“删除”)

在上面的示例中,观察 1 中的 NA 值应保持为 NA。但是,观察 4 和 5 中的 NA 值应更改为“删除”。

【问题讨论】:

  • 你的实际数据的结构是什么?请使用dput(name_of_object) 发布它的样本。使用字符串 "remove" 作为标志在包含数字数据的 data.frame 中会出现问题,因为您不能在给定列中混合数字和非数字值。
  • 感谢您的及时回复。该对象是一个仅包含数值变量的数据框。我说删除只是一个例子,它可以是任何数字作为标志。
  • 我知道您说的是按行排列,但 observation 1observation 2 等是单独的列,您想对数据框/表的每一行执行此操作吗?
  • 是的,观察 1、观察 2... 等是单独的列。它是一个转置的数据框。没错,我想对整个数据框执行此操作。

标签: r na


【解决方案1】:

你可以定义函数:

replace.na <- function(r,val) {
  i <- is.na(r)
  j <- which(i)
  k <- which(!i)
  r[j[j > k[length(k)]]] <- val
  r
}

那么,假设你有一个像这样的data.frame

r <- data.frame(ID=c('A','B'),obs1=c(NA,1),obs2=c(0,NA),obs3=c(1,2),obs4=c(NA,3),obs5=c(NA,NA))
##  ID obs1 obs2 obs3 obs4 obs5
##1  A   NA    0    1   NA   NA
##2  B    1   NA    2    3   NA

我们可以在r的所有数字列的行上使用apply函数:

r[,-1] <- t(apply(r[,-1],1,replace.na,999))    
##  ID obs1 obs2 obs3 obs4 obs5
##1  A   NA    0    1  999  999
##2  B    1   NA    2    3  999

这会将r[,-1] 视为matrixapply 的输出填充matrix,默认情况下由列填充。因此,在将列替换回r之前,我们必须转置得到的matrix

拨打replace.na的另一种方式是:

r[,-1] <- do.call(rbind,lapply(data.frame(t(r[,-1])),replace.na,999))

在这里,我们首先转置r 的数字列,并将其设为data.frame。这使得r 的每一行在作为结果数据框的列列表中成为一列。然后在这些列上使用lapply 以应用replace.narbind 的结果。


如果你想在第一个非NA之后标记所有NA,那么函数replace.na应该是:

replace.na <- function(r,val) {
  i <- is.na(r)
  j <- which(i)
  k <- which(!i)
  r[j[j > k[1]]] <- val
  r
}

将其应用于数据:

r[,-1] <- do.call(rbind,lapply(data.frame(t(r[,-1])),replace.na,999))
##  ID obs1 obs2 obs3 obs4 obs5
##1  A   NA    0    1  999  999
##2  B    1  999    2    3  999

【讨论】:

  • 太棒了@aichao...即使我在尝试类似的东西,但你做到了!
  • 如果我想将 obs2 更改为 999,解决方案是什么 r[j[j = k[length(k)]]]
  • 非常感谢!很有帮助。
  • @User2321:第一个版本只会将 lastNA 之后的所有NA 替换为替换值。因此,对于您的数据r &lt;- c(NA, 0, 1, NA, NA, 1),我们得到replace.na(r,5) 的结果[1] NA 0 1 NA NA 1。也就是说,由于r 中的最后一个值不是NA,因此不会替换任何内容。第二个版本将 firstNA 之后的所有NA 替换为替换值。在这种情况下,replace.na(r,5) 给出[1] NA 0 1 5 5 1
猜你喜欢
  • 1970-01-01
  • 2016-12-12
  • 1970-01-01
  • 2018-03-19
  • 2018-06-20
  • 2011-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多