这个问题不重复,因为我的data.frame
在所有列中的NA
值都不相同,因此该问题中提到的解决方案不起作用。
我有一个data.frame
,其中包含很多NA
个值,我想删除所有具有NA值的单元格(重要:不是行或列,单元格)。原件看起来像这样:
A B
1 NA
NA 2
2 NA
NA NA
NA NA
NA 4
3 5
期望的结果如下所示:
A B
1 2
2 4
3 5
列数必须保持不变,但如果值保留在同一行上则无关紧要。他们可以向上移动。
我可以想象一个可以删除条件为NA的所有单元格(可能是应用)并获得结果。或者也许是简单的排序?
感谢。
更新
A B C
1 3
2
4 3
1 2
3 5
4
9
7 1
答案 0 :(得分:1)
您可以尝试,根据@ UweBlock的数据和您更新的问题。
dat=as.data.frame(na.omit(apply(dat,2,function (x) x[order(is.na(x))])))
dat
A B C
1 1 2 3
2 4 1 3
3 3 9 2
答案 1 :(得分:1)
OP要求按列删除NA
,但已指出每列中可能有不同数量的NA。
这可以通过两个步骤使用data.table
来解决:
library(data.table)
# step 1: coerce to data.table in place, move NAs to the bottom of each column,
# maintain the original order of non-NA values
result <- data.table(DF)[, lapply(.SD, function(x) x[order(is.na(x))])]
A B C 1: 1 2 3 2: 4 1 3 3: 3 9 2 4: 7 NA 5 5: NA NA 4 6: NA NA 1 7: NA NA NA 8: NA NA NA 9: NA NA NA 10: NA NA NA
# step 2: trim result
# either using Reduce
result[!result[, Reduce(`&`, lapply(.SD, is.na))]]
# or using zoo::na.trim()
zoo::na.trim(result, is.na = "all")
A B C 1: 1 2 3 2: 4 1 3 3: 3 9 2 4: 7 NA 5 5: NA NA 4 6: NA NA 1
因此,不可避免地会在每个列的末尾有一些NA
因为data.frame中的所有列都具有相同的长度。
或者,也可以使用is.na
参数na.trim()
仅保留完整的行:
zoo::na.trim(result, is.na = "any")
A B C 1: 1 2 3 2: 4 1 3 3: 3 9 2
如前所述,data.frame
和cbind()
期望所有列向量具有相同的长度。这是一个没有data.table
的替代解决方案,该解决方案使用cbind.fill()
包中的rowr
函数,该函数将具有fill
值的向量填充到相同的长度:
setNames(do.call(function(...) rowr::cbind.fill(..., fill = NA), lapply(DF, na.omit)),
colnames(DF))
A B C 1 1 2 3 2 4 1 3 3 3 9 2 4 7 NA 5 5 NA NA 4 6 NA NA 1
由更新中的OP提供:
DF <- structure(list(A = c(1L, NA, 4L, NA, NA, NA, 3L, NA, NA, 7L),
B = c(NA, 2L, NA, NA, 1L, NA, NA, NA, 9L, NA), C = c(3L,
NA, 3L, NA, 2L, NA, 5L, 4L, NA, 1L)), .Names = c("A", "B",
"C"), row.names = c(NA, -10L), class = "data.frame")