合并包含NA的数据框中的行以生成完整的行

CPa*_*Pak 10 r coalesce tidyverse

我知道这是一个重复的Q但我似乎无法再找到这个帖子

使用以下数据

df <- data.frame(A=c(1,1,2,2),B=c(NA,2,NA,4),C=c(3,NA,NA,5),D=c(NA,2,3,NA),E=c(5,NA,NA,4))

  A  B  C  D  E
  1 NA  3 NA  5
  1  2 NA  2 NA
  2 NA NA  3 NA
  2  4  5 NA  4
Run Code Online (Sandbox Code Playgroud)

分组A,我想使用tidyverse解决方案的以下输出

  A  B  C  D  E
  1  2  3  2  5
  2  4  5  3  4
Run Code Online (Sandbox Code Playgroud)

我有很多小组A.我想我看到了一个答案,coalesce但我不确定如何让它发挥作用.我想要一个同样适用characters解决方案.谢谢!

www*_*www 18

我们可以用它fill来填充所有缺失的值。然后为每组仅过滤一行。

library(dplyr)
library(tidyr)

df2 <- df %>%
  group_by(A) %>%
  fill(everything(), .direction = "down") %>%
  fill(everything(), .direction = "up") %>%
  slice(1)
Run Code Online (Sandbox Code Playgroud)

并且感谢@Roger-123,上面的代码可以进一步简化如下。

df2 <- df %>%
  group_by(A) %>%
  fill(everything(), .direction = "downup") %>%
  slice(1)
Run Code Online (Sandbox Code Playgroud)

  • 这也可以通过将第一条填充线从“向下”更改为“向下向上”并删除第二条填充线来简化。 (2认同)

Ori*_*osa 8

我还没弄明白如何将coalesce_by_column函数放入dplyr管道中,但这有效:

coalesce_by_column <- function(df) {
  return(coalesce(df[1], df[2]))
}

df %>%
  group_by(A) %>%
  summarise_all(coalesce_by_column)

##       A     B     C     D     E
##   <dbl> <dbl> <dbl> <dbl> <dbl>
## 1     1     2     3     2     5
## 2     2     4     5     3     4
Run Code Online (Sandbox Code Playgroud)

编辑:包括@Jon Harmon的超过2名成员的解决方案

# Supply lists by splicing them into dots:
coalesce_by_column <- function(df) {
  return(dplyr::coalesce(!!! as.list(df)))
}

df %>%
  group_by(A) %>%
  summarise_all(coalesce_by_column)

#> # A tibble: 2 x 5
#>       A     B     C     D     E
#>   <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1     1     2     3     2     5
#> 2     2     4     5     3     4
Run Code Online (Sandbox Code Playgroud)

  • 从dplyr :: coalesce帮助:#通过将它们拼接成点来提供列表:vecs < - list(c(1,2,NA,NA,5),c(NA,NA,3,4,5))coalesce( !!! vecs)所以,基于此,我得到coalesce_by_column为一个组的2个以上成员工作:coalesce_by_column < - function(df){return(dplyr :: coalesce(!!! as.list(df))希望有所帮助! (3认同)

d.b*_*d.b 5

不是tidyverse,这是一个基础R解决方案

df <- data.frame(A=c(1,1),B=c(NA,2),C=c(3,NA),D=c(NA,2),E=c(5,NA))
sapply(df, function(x) x[!is.na(x)][1])
#A B C D E 
#1 2 3 2 5 
Run Code Online (Sandbox Code Playgroud)

随着更新的数据

do.call(rbind, lapply(split(df, df$A), function(a) sapply(a, function(x) x[!is.na(x)][1])))
#  A B C D E
#1 1 2 3 2 5
#2 2 4 5 3 4
Run Code Online (Sandbox Code Playgroud)