62

Rにいくつかの列があり、各行にはそのうちの1つにのみ値があり、残りはNAになります。これらを非NA値の1つの列に結合したいと思います。誰かがこれを行う簡単な方法を知っていますか?たとえば、私は次のようにすることができます:

data <- data.frame('a' = c('A','B','C','D','E'),
                   'x' = c(1,2,NA,NA,NA),
                   'y' = c(NA,NA,3,NA,NA),
                   'z' = c(NA,NA,NA,4,5))

だから私は

'a' 'x' 'y' 'z'  
 A   1   NA  NA  
 B   2   NA  NA  
 C  NA   3   NA  
 D  NA   NA  4  
 E  NA   NA  5

そして、私は得るだろう

 'a' 'mycol'  
  A   1  
  B   2  
  C   3  
  D   4  
  E   5  

NAを含む列の名前は、クエリの前半のコードによって変わるため、列名を明示的に呼び出すことはできませんが、NAを含む列の列名は、ベクトルとして格納されています。たとえば、この例cols <- c('x','y','z')では、したがって、を使用して列を呼び出すことができますdata[, cols]

どんな助けでもいただければ幸いです。

ありがとう

4

10 に答える 10

54

ベースのdplyr::coalesceソリューションは次のようになります。

data %>% mutate(mycol = coalesce(x,y,z)) %>%
         select(a, mycol)
#   a mycol
# 1 A     1
# 2 B     2
# 3 C     3
# 4 D     4
# 5 E     5 

データ

data <- data.frame('a' = c('A','B','C','D','E'),
                 'x' = c(1,2,NA,NA,NA),
                 'y' = c(NA,NA,3,NA,NA),
                 'z' = c(NA,NA,NA,4,5))
于 2018-04-15T09:32:58.377 に答える
22

unlist列を1つのベクトルに変換するために使用できます。後で、na.omitを削除するために使用できますNA

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

   a mycol
x1 A     1
x2 B     2
y3 C     3
z4 D     4
z5 E     5
于 2013-01-28T13:56:08.097 に答える
15

これは、順序付けされていないNAを持つすべての列タイプ(因子、文字など)に拡張される、より一般的な(ただしさらに単純な)ソリューションです。is.na戦略は、インデックス作成に使用して、他の列の非NA値をマージされた列にマージすることです。

data$m = data$x  # your new merged column start with x
data$m[!is.na(data$y)] = data$y[!is.na(data$y)]  # merge with y
data$m[!is.na(data$z)] = data$z[!is.na(data$z)]  # merge with z

> data
  a  x  y  z m
1 A  1 NA NA 1
2 B  2 NA NA 2
3 C NA  3 NA 3
4 D NA NA  4 4
5 E NA NA  5 5

m同じ行にNA以外の値が複数ある場合、これにより既存の値が上書きされることに注意してください。列がたくさんある場合は、ループすることでこれを自動化できますcolnames(data)

于 2014-11-05T13:40:32.217 に答える
14

私は引数で使用rowSums()na.rm = TRUEます:

cbind.data.frame(a=data$a, mycol = rowSums(data[, -1], na.rm = TRUE))

これは次のようになります。

> cbind.data.frame(a=data$a, mycol = rowSums(data[, -1], na.rm = TRUE))
  a mycol
1 A     1
2 B     2
3 C     3
4 D     4
5 E     5

cbind.data.frame上記の最初の引数はデータフレームではないため、メソッドを直接呼び出す必要があります( )。

于 2013-01-28T14:02:59.877 に答える
5

このようなもの ?

data.frame(a=data$a, mycol=apply(data[,-1],1,sum,na.rm=TRUE))

与える:

  a mycol
1 A     1
2 B     2
3 C     3
4 D     4
5 E     5
于 2013-01-28T13:57:21.307 に答える
1

maxも機能します。文字列ベクトルでも機能します。

cbind(data[1], mycol=apply(data[-1], 1, max, na.rm=T))
于 2016-09-20T18:55:02.203 に答える
0

関連するリンク(paste()でNAを抑制する)pasteで、オプション付きのバージョンを提示しna.rmます(残念な名前はpaste5)。

これでコードは次のようになります

cols <- c("x", "y", "z")
cbind.data.frame(a = data$a, mycol = paste2(data[, cols], na.rm = TRUE))

の出力はpaste5文字です。文字データがある場合は機能します。それ以外の場合は、必要なタイプに強制変換する必要があります。

于 2015-12-16T10:37:07.230 に答える
0

これはOPの場合ではありませんが、答えをより普遍的にするために、合計に基づくアプローチを好む人もいるようです。この答えは、多くの人が見つけるタイトルと一致します。

data <- data.frame('a' = c('A','B','C','D','E'),
                   'x' = c(1,2,NA,NA,9),
                   'y' = c(NA,6,3,NA,5),
                   'z' = c(NA,NA,NA,4,5))

splitdf<-split(data[,c(2:4)], seq(nrow(data[,c(2:4)])))

data$mean<-unlist(lapply(splitdf, function(x)  mean(unlist(x), na.rm=T) ) )
data$mode<-unlist(lapply(splitdf, function(x)  {
  tab <- tabulate(match(x, na.omit(unique(unlist(x) )))); 
                  paste(na.omit(unique(unlist(x) ))[tab == max(tab) ], collapse = ", " )}) )

data
  a  x  y  z     mean mode
1 A  1 NA NA 1.000000    1
2 B  2  6 NA 4.000000 2, 6
3 C NA  3 NA 3.000000    3
4 D NA NA  4 4.000000    4
5 E  9  5  5 6.333333    5
于 2017-08-25T17:58:32.603 に答える
0

dplyrを使用する1つの可能性は、次のtidyrとおりです。

data %>%
 gather(variables, mycol, -1, na.rm = TRUE) %>%
 select(-variables)

   a mycol
1  A     1
2  B     2
8  C     3
14 D     4
15 E     5

ここでは、この操作から最初の列を除外し、NAを削除して、データをワイド形式からロング形式に変換します。

于 2019-05-03T21:13:09.730 に答える
0

ベースにこだわるなら、

data <- data.frame('a' = c('A','B','C','D','E'),'x' = c(1,2,NA,NA,NA),'y' = c(NA,NA,3,NA,NA),'z' = c(NA,NA,NA,4,5))
data[is.na(data)]<-","
data$mycol<-paste0(data$x,data$y,data$z)
data$mycol <- gsub(',','',data$mycol)
于 2019-10-15T12:48:54.957 に答える