簡體   English   中英

按行合並所有列

[英]Row-wise coalesce over all columns

我們如何在不指定列名的情況下對所有列使用dplyr ( tidyverse ) 按行獲取第一個非缺失值 -合並

示例數據:

df <- data.frame(x = c(NA, "s3", NA, NA,"s4"),
                 y = c("s1", NA, "s6", "s7", "s4"),
                 z = c("s1", NA, NA, "s7", NA))

我們可以使用do.call ,但這看起來不太整潔:

df$xyz <- do.call(coalesce, df)
#      x    y    z xyz
# 1 <NA>   s1   s1  s1
# 2   s3 <NA> <NA>  s3
# 3 <NA>   s6 <NA>  s6
# 4 <NA>   s7   s7  s7
# 5   s4   s4 <NA>  s4

這有效,但我不想指定列:

df %>% 
  mutate(xyz = coalesce(x, y, z))
#      x    y    z xyz
# 1 <NA>   s1   s1  s1
# 2   s3 <NA> <NA>  s3
# 3 <NA>   s6 <NA>  s6
# 4 <NA>   s7   s7  s7
# 5   s4   s4 <NA>  s4

類似於data.table

library(data.table)
setDT(df)[, xyz := fcoalesce(.SD) ][]
#       x    y    z xyz
# 1: <NA>   s1   s1  s1
# 2:   s3 <NA> <NA>  s3
# 3: <NA>   s6 <NA>  s6
# 4: <NA>   s7   s7  s7
# 5:   s4   s4 <NA>  s4

失敗的嘗試:

df %>% 
  mutate(xyz = coalesce(all_vars()))

df %>% 
  mutate(xyz = coalesce(c_across(all_vars())))

df %>% 
  rowwise() %>% 
  mutate(xyz = coalesce(all_vars()))

df %>% 
  rowwise() %>% 
  mutate(xyz = coalesce(c_across(all_vars())))

有任何想法嗎?

取自這個GitHub 討論,你可以創建一個coacross function:

coacross <- function(...) {
  coalesce(!!!across(...))
}

df %>% 
  mutate(xyz = coacross(everything()))

     x    y    z xyz
1 <NA>   s1   s1  s1
2   s3 <NA> <NA>  s3
3 <NA>   s6 <NA>  s6
4 <NA>   s7   s7  s7
5   s4   s4 <NA>  s4

我們可以使用拼接運算符注入數據框進行coalesce !!! .

library(dplyr)

df %>% mutate(xyz = coalesce(!!!df))

或者更像“tidyverse”:

df %>% mutate(xyz = coalesce(!!!select(., everything())))

Output

     x    y    z xyz
1 <NA>   s1   s1  s1
2   s3 <NA> <NA>  s3
3 <NA>   s6 <NA>  s6
4 <NA>   s7   s7  s7
5   s4   s4 <NA>  s4

這是可能的解決方案:

df %>%
    mutate(xyz = do.call(coalesce,across()))

#>     x    y    z xyz
#> 1 <NA>   s1   s1  s1
#> 2   s3 <NA> <NA>  s3
#> 3 <NA>   s6 <NA>  s6
#> 4 <NA>   s7   s7  s7
#> 5   s4   s4 <NA>  s4

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM