web-dev-qa-db-ja.com

RのNA値でドロップ行をサブセット化する効率的な方法

背景段階的なモデル選択を実行する前に、モデル用語の欠落している値を削除する必要があります。したがって、私のモデルにはかなりの数の項があるため、NA値を探す必要がある(そしてそれらのベクトルのいずれかにNA値を持つ行を削除する)必要のあるベクトルがかなりあります。ただし、行を削除するための用語/基準として使用したくないNA値を含むベクトルもあります。

質問ベクトルのリストのいずれかのNA値を含むデータフレームから行を削除するにはどうすればよいですか?私は現在、!is.naの長いシリーズの不格好な方法を使用しています

> my.df[!is.na(my.df$termA)&!is.na(my.df$termB)&!is.na(my.df$termD),]

しかし、もっとエレガントな方法があると確信しています。

8
Oreotrephes

datをデータフレームとし、colsを対象の列名または列番号のベクトルとします。その後、あなたは使用することができます

dat[!rowSums(is.na(dat[cols])), ]

少なくとも1つのNAを持つすべての行を除外します。

12
Sven Hohenstein

編集:私はsubset、物事をサブセット化するために作られた組み込み関数を完全に理解しました:

_my.df <- subset(my.df, 
  !(is.na(termA) |
    is.na(termB) |
    is.na(termC) )
  )
_

私はこのようなことにwith()を使う傾向があります。 attachを使用しないでください。自分でカットする必要があります。

_my.df <- my.df[with(my.df, {
  !(is.na(termA) |
    is.na(termB) |
    is.na(termC) )
}), ]
_

ただし、これを頻繁に行う場合は、ヘルパー関数is_any()も必要になる場合があります。

_is_any <- function(x){
  !is.na(x)
}
_

この種のことをたくさん行うことになった場合、SQLを使用すると、データのサブセットとのやり取りがうまくいくことがよくあります。 dplyr も役立つ場合があります。

7
Tyler

これは1つの方法です:

_#  create some random data
df <- data.frame(y=rnorm(100),x1=rnorm(100), x2=rnorm(100),x3=rnorm(100))
# introduce random NA's
df[round(runif(10,1,100)),]$x1 <- NA
df[round(runif(10,1,100)),]$x2 <- NA
df[round(runif(10,1,100)),]$x3 <- NA

# this does the actual work...
# assumes data is in columns 2:4, but can be anywhere
for (i in 2:4) {df <- df[!is.na(df[,i]),]}
_

そして、sapply(...)Reduce(...)を使用した別の方法を次に示します。

_xx <- data.frame(!sapply(df[2:4],is.na))
yy <- Reduce("&",xx)
zz <- df[yy,]
_

最初のステートメントは、関数is.na(...)dfの列2:4に「適用」し、結果を反転します(_!NA_が必要です)。 2番目のステートメントは、論理_&_演算子をxxの列に連続して適用します。 3番目のステートメントは、_yy=T_の行のみを抽出します。明らかに、これは1つの恐ろしく複雑なステートメントに組み合わせることができます。

_zz <-df[Reduce("&",data.frame(!sapply(df[2:4],is.na))),]
_

列が非常に多い場合は、sapply(...)Reduce(...)を使用すると高速になります。

最後に、ほとんどのモデリング関数には、NAを直接処理するように設定できるパラメーターがあります(これらすべてに頼ることなく)。たとえば、 lm(...) の_na.action_パラメータを参照してください。

1
jlhoward