删除相关的NA

时间:2016-01-04 17:41:58

标签: r

以前有一个关于根据相关缺失的NA创建新数据帧的问题。如果一个NA处于一个奇数索引,则该索引+下一个被删除,如果它是偶数,则该索引 - 前一个被删除。这是代码:

is.odd <- function(x) x %% 2 == 1
apply(new, 1, function(x) {
    toremove <-which(is.na(x))
    toremove1<-sapply(toremove,function(x) ifelse(is.odd(x),x+1,x-1) )
    ref[,!(1:ncol(ref) %in% c(toremove,toremove1)),drop=F]
})

我正在尝试重写这个用于类似的目的,现在从数据帧new中删除NA,但是将每一行打印为单独的数据帧。我真的很讨厌R如何处理与apply系列的循环,并且无法解决这个问题。例如:

  var1  var2  var3 var4
1  a     NA    c    1
2  d     e     f    2
3  NA    h     I    3

成为三个数据帧:

  var3  var4
1   c      1

  var1  var2  var3 var4
2  d     e     f    2

     var3 var4
3     I    3

作为对此的更新,有人可以为具有c / c ++背景的人推荐一本好的R书吗?

1 个答案:

答案 0 :(得分:3)

复制数据并创建data.frame:

df <- read.table(header = TRUE, text = "var1  var2  var3 var4
1  a     NA    c    1
2  d     e     f    2
3  NA    h     I    3")

查找具有NA值的列和行:

c <- col(df)[is.na(df)]
r <- row(df)[is.na(df)]

以偶数/奇数为条件获得正确的相邻列:

d <- ifelse(c %% 2 == 1, c + 1, c - 1)

遍历只有NAs的行来修改它们:

modified <- lapply(seq_along(r), function(i) {
  remove <- -(c(d[i], c[i]))
  df[r[i], remove, drop=F]
})

只需删除带有NAs的行以获取其他行

unmodified <- split(df[-r, ], (1:nrow(df))[-r])

使用data.frames列表执行任何操作

编辑:

这是输出

> modified
[[1]]
  var3 var4
3    I    3

[[2]]
  var3 var4
1    c    1

> unmodified
$`2`
  var1 var2 var3 var4
2    d    e    f    2

编辑连续考虑多个NAs:

c <- col(df)[is.na(df)]
r <- row(df)[is.na(df)]
d <- ifelse(c %% 2 == 1, c + 1, c - 1)

按行汇总所有列索引:

ids <- split(cbind(d, c), r)
na.rows <- unique(sort(r))

modified <- lapply(seq_along(na.rows), function(i) {
  df[na.rows[i], -(ids[[i]]), drop=F]
})

unmodified <- split(df[-na.rows, ], (1:nrow(df))[-na.rows])

编辑以使列表与原始data.frame的顺序相同:

您可以通过简单地正确索引新列表,将修改后的列表插入新列表中。

recombined <- list()
recombined[na.rows] <- modified
recombined[(1:nrow(df))[-na.rows]] <- unmodified