2017-08-22 68 views
0

這是this earlier question的擴展。我怎樣才能結合了數據幀的兩列如何將數據框的兩列與缺失數據結合?

data <- data.frame('a' = c('A','B','C','D','E'), 
        'x' = c("t",2,NA,NA,NA), 
        'y' = c(NA,NA,NA,4,"r")) 

顯示爲

'a' 'x' 'y' 
A t NA 
B 2 NA 
C NA NA 
D NA 4 
E NA r 

得到

'a' 'mycol' 
    A t 
    B 2 
    C NA 
    D 4 
    E r 

我想這

cbind(data[1], mycol = na.omit(unlist(data[-1]))) 

但它顯然沒有按保持NA行。

+2

建議受騙者:?如何實現R中聚結(https://stackoverflow.com/q/19253820/903061) – Gregor

+0

這種情況是很簡單的,你可以做'pmin'或'pmax',例如'data $ mycol = pmin(data $ x,data $ y,na.rm = T)'。這可以擴展到更多的列,但是如果存在多個非缺失值,它將選擇最小值。在建議的重複中的聚結答案將選擇第一個非缺失值。 – Gregor

+0

其他相關的Q只適用於一個簡單的例子,只有一個非'N'列; [將兩個合適的字符串列結合到R中的一個](https://stackoverflow.com/questions/27850344/combine-two-fitting-string-columns-to-one-in-r) – Henrik

回答

0

您可以通過使用ifelse,這樣做:

data$mycol <- ifelse(!is.na(data$x), data$x, data$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 
+2

在OP的情況下工作良好,但如果涉及更多列,則不能很好地縮放... – Gregor

0

用你的邏輯去,你可以做到以下幾點:

cbind(data[1], mycol = unlist(apply(data[2:3], 1, function(i) ifelse(
    length(is.na(i))==length(i), 
    na.omit(i), 
    NA) 
))) 

# a mycol 
#1 A  1 
#2 B  2 
#3 C NA 
#4 D  4 
#5 E  5 
0

這已間接尋址here。這是基於這樣一個簡單的解決方案:

data$mycol <- coalesce(data$x, data$y) 
0

擴展答案任意數量的列,並使用純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 
+0

比較的任何優點到[mrip的閃電般快速的答案在這裏?](https://stackoverflow.com/a/19254510/903061) – Gregor

+0

是的,它可以更好地擴展到更多列。添加比較以回答... –

相關問題