web-dev-qa-db-ja.com

NAを含むデータフレームの行を組み合わせて、完全な行を作成します

これが重複した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

Aでグループ化すると、tidyverseソリューションを使用して次の出力が必要です

  A  B  C  D  E
  1  2  3  2  5
  2  4  5  3  4

Aにはたくさんのグループがあります。 coalesceを使用して答えを見たと思いますが、それを機能させる方法がわかりません。 charactersでも機能するソリューションが欲しいのですが。ありがとう!

12
CPak

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

編集:グループの2人以上のメンバーのための@JonHarmonのソリューションを含める

# 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
5
Oriol Mirosa

tidyverseではありませんが、ここに1つのベース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 

更新されたデータ

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
5
d.b

これはさらに一般的な解決策です(uniquena.omitcoalesce)を作成します。これは、重複する情報を持つ3つ以上の行を処理できます。超シンプルでフォワード。

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

> df
  A  B  C  D  E
1 1 NA  3 NA  5
2 1  2 NA  2 NA
3 2 NA NA  3 NA
4 2  4  5 NA  4
5 2  4 NA NA  4

> df %>% group_by(A) %>% summarise_all(funs( na.omit(unique(.)) ))
# 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
3
Jerry T

fillを使用して、不足しているすべての値を埋めることができます。次に、グループごとに1行だけをフィルタリングします。

library(dplyr)
library(tidyr)

df2 <- df %>%
  group_by(A) %>%
  fill(everything(), .direction = "down") %>%
  fill(everything(), .direction = "up") %>%
  slice(1)
2
www