这个问题不是重复的,因为我的值data.frame 不同NA in all Columns and therefore the solution mentioned in that question does not work.
我有data.frame很多NA值,我想删除所有具有 NA 值的单元格(重要:不是行或列,单元格)。原来的样子是这样的:
A B
1 NA
NA 2
2 NA
NA NA
NA NA
NA 4
3 5
Run Code Online (Sandbox Code Playgroud)
期望的结果如下所示:
A B
1 2
2 4
3 5
Run Code Online (Sandbox Code Playgroud)
列数必须保持相同,但值是否保留在同一行上也没关系。他们可以向上移动。
我可以想象可以删除所有具有 NA 条件(也许具有 apply)的单元格并获得结果。或者也许是一个简单的排序?
谢谢。
更新:
A B C
1 3
2
4 3
1 2
3 5
4
9
7 1
Run Code Online (Sandbox Code Playgroud)
OP 要求NA按列删除 s,但指出每列中可能有不同数量的 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))])]
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)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")
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)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因此,每列的末尾不可避免地会有一些s,因为 data.frame 中的所有列都具有相同的长度。
或者,也可以使用is.na参数 to只保留完整的行na.trim():
zoo::na.trim(result, is.na = "any")
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)A B C 1: 1 2 3 2: 4 1 3 3: 3 9 2
如前所述,data.frames 并cbind()期望所有列向量具有相同的长度。这是一个替代解决方案,如果不使用该解决方案data.table,则使用包cbind.fill()中的函数rowr,该函数用值填充向量fill直到长度相同:
setNames(do.call(function(...) rowr::cbind.fill(..., fill = NA), lapply(DF, na.omit)),
colnames(DF))
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)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")
Run Code Online (Sandbox Code Playgroud)