【发布时间】:2016-02-06 01:01:46
【问题描述】:
假设你有以下数据框:
dat <- data.frame(a = c(1:3, NA), b = c(letters[1:3], NA), c = NA)
> dat
a b c
1 1 a NA
2 2 b NA
3 3 c NA
4 NA <NA> NA
如何以非常有效的方式选择非 NA 区域?
这是我目前使用的:
ensureNonNaRange <- function(dat) {
idx_col <- ! sapply(dat, function(ii) all(is.na(ii)))
idx_row <- ! sapply(1:nrow(dat), function(ii) all(is.na(unlist(dat[ii, ]))))
dat[idx_row, idx_col]
}
> ensureNonNaRange(dat)
a b
1 1 a
2 2 b
3 3 c
直到今天我才被指出了一个非常有用的函数 type.convert,这是我以前不知道的,我认为在 base R 中可能还存在一些类似于此任务的“现成”的东西。
更新
基于我得到的答案/cmets的一些比较:
ensureNonNaRange2 <- function(dat) {
dat[rowSums(!is.na(dat)) != 0, colSums(!is.na(dat)) != 0]
}
microbenchmark::microbenchmark(
a = ensureNonNaRange(dat),
b = ensureNonNaRange2(dat)
)
Unit: microseconds
expr min lq mean median uq max neval
a 296.178 310.1070 346.2259 329.0210 349.9875 680.035 100
b 112.313 120.0845 134.1716 125.6555 133.7200 338.112 100
【问题讨论】:
-
不是现成的,而是在一行中:
dat[rowSums(!is.na(dat)) != 0, colSums(!is.na(dat)) != 0] -
@alistaire:整洁!几乎是我的两倍,而且非常紧凑。非常感谢!想提供这个作为答案吗?
-
如果
dat[2, 3]不是 NA?