擴展答案任意數量的列,並使用純max.col()
功能我發現多虧了這個問題:
coalesce <- function(value_matrix) {
value_matrix <- as.matrix(value_matrix)
first_non_missing <- max.col(!is.na(value_matrix), ties.method = "first")
indices <- cbind(
row = seq_len(nrow(value_matrix)),
col = first_non_missing
)
value_matrix[indices]
}
data$mycol <- coalesce(data[, c('x', 'y')])
data
# a x y mycol
# 1 A 1 NA 1
# 2 B 2 NA 2
# 3 C NA NA NA
# 4 D NA 4 4
# 5 E NA 5 5
max.col(..., ties.method = "first")
回報,對於每一行,第一列的索引具有最大值。由於我們在邏輯矩陣上使用它,所以最大值通常是TRUE
。所以我們將得到每行的第一個非NA
值。如果整行是NA
,那麼我們將根據需要得到NA
的值。
之後,該函數使用行列索引矩陣來對這些值進行子集合。
編輯
相較於mrip's coalesce,我max.col
較慢時,有幾個長列,但是當有許多短柱更快。
coalesce_reduce <- function(...) {
Reduce(function(x, y) {
i <- which(is.na(x))
x[i] <- y[i]
x},
list(...))
}
coalesce_maxcol <- function(...) {
value_matrix <- cbind(...)
first_non_missing <- max.col(!is.na(value_matrix), ties.method = "first")
indices <- cbind(
row = seq_len(nrow(value_matrix)),
col = first_non_missing
)
value_matrix[indices]
}
set.seed(100)
wide <- replicate(
1000,
{sample(c(NA, 1:10), 10, replace = TRUE)},
simplify = FALSE
)
long <- replicate(
10,
{sample(c(NA, 1:10), 1000, replace = TRUE)},
simplify = FALSE
)
microbenchmark(
do.call(coalesce_reduce, wide),
do.call(coalesce_maxcol, wide),
do.call(coalesce_reduce, long),
do.call(coalesce_maxcol, long)
)
# Unit: microseconds
# expr min lq mean median uq max neval
# do.call(coalesce_reduce, wide) 1879.460 1953.5695 2136.09954 2007.303 2152.654 5284.583 100
# do.call(coalesce_maxcol, wide) 403.604 423.5280 490.40797 433.641 456.583 2543.580 100
# do.call(coalesce_reduce, long) 36.829 41.5085 45.75875 43.471 46.942 79.393 100
# do.call(coalesce_maxcol, long) 80.903 88.1475 175.79337 92.374 101.581 3438.329 100
建議受騙者:?如何實現R中聚結(https://stackoverflow.com/q/19253820/903061) – Gregor
這種情況是很簡單的,你可以做'pmin'或'pmax',例如'data $ mycol = pmin(data $ x,data $ y,na.rm = T)'。這可以擴展到更多的列,但是如果存在多個非缺失值,它將選擇最小值。在建議的重複中的聚結答案將選擇第一個非缺失值。 – Gregor
其他相關的Q只適用於一個簡單的例子,只有一個非'N'列; [將兩個合適的字符串列結合到R中的一個](https://stackoverflow.com/questions/27850344/combine-two-fitting-string-columns-to-one-in-r) – Henrik