data.frame内の全部または一部のNA(欠損値)を含む行を削除する。

このデータフレームで、以下のような行を削除したいのです:

a) すべての列でNAを含む。以下は私のデータフレーム例です。

             gene hsap mmul mmus rnor cfam
1 ENSG00000208234    0   NA   NA   NA   NA
2 ENSG00000199674    0   2    2    2    2
3 ENSG00000221622    0   NA   NA   NA   NA
4 ENSG00000207604    0   NA   NA   1    2
5 ENSG00000207431    0   NA   NA   NA   NA
6 ENSG00000221312    0   1    2    3    2

基本的には、以下のようなデータフレームを取得したいのですが。

             gene hsap mmul mmus rnor cfam
2 ENSG00000199674    0   2    2    2    2
6 ENSG00000221312    0   1    2    3    2

b) 一部のカラムにのみNAを含む、この結果も得ることができる:

             gene hsap mmul mmus rnor cfam
2 ENSG00000199674    0   2    2    2    2
4 ENSG00000207604    0   NA   NA   1    2
6 ENSG00000221312    0   1    2    3    2
ソリューション

また、complete.casesもご確認ください:

> final[complete.cases(final), ]
             gene hsap mmul mmus rnor cfam
2 ENSG00000199674    0    2    2    2    2
6 ENSG00000221312    0    1    2    3    2

na.omitは、すべてのNA's を削除するのに適しています。complete.casesは、データフレームの特定のカラムのみを含むことで部分選択を可能にする:

> final[complete.cases(final[ , 5:6]),]
             gene hsap mmul mmus rnor cfam
2 ENSG00000199674    0    2    2    2    2
4 ENSG00000207604    0   NA   NA    1    2
6 ENSG00000221312    0    1    2    3    2

あなたの解決策はうまくいきません。もし、どうしてもis.naを使いたいのであれば、次のようなことをしなければなりません:

> final[rowSums(is.na(final[ , 5:6])) == 0, ]
             gene hsap mmul mmus rnor cfam
2 ENSG00000199674    0    2    2    2    2
4 ENSG00000207604    0   NA   NA    1    2
6 ENSG00000221312    0    1    2    3    2

が、complete.casesを使ったほうが、かなりわかりやすく、スピードも速いです。

解説 (10)

na.omit(your.data.frame)`を試してみてください。2つ目の質問については、別の質問として投稿してみてください(わかりやすくするため)。

解説 (3)

tidyrには新しい関数[drop_na]があります(https://blog.rstudio.org/2016/08/15/tidyr-0-6-0/):

library(tidyr)
df %>% drop_na()
#              gene hsap mmul mmus rnor cfam
# 2 ENSG00000199674    0    2    2    2    2
# 6 ENSG00000221312    0    1    2    3    2
df %>% drop_na(rnor, cfam)
#              gene hsap mmul mmus rnor cfam
# 2 ENSG00000199674    0    2    2    2    2
# 4 ENSG00000207604    0   NA   NA    1    2
# 6 ENSG00000221312    0    1    2    3    2
解説 (5)

行にNAが含まれているかどうかをチェックする方法は、次のようなものがあります:


row.has.na 
解説 (2)

行が無効であると見なされる方法をより詳細に制御したい場合は、別のオプションがあります。


final 
解説 (1)

各行に有効なNAの数を制御する場合は、この機能を試してください。 多くの調査データセットでは、空白の質問の回答が多すぎると結果が台無しになる可能性があります。 したがって、特定のしきい値の後に削除されます。 この関数を使用すると、行が削除される前に実行できるNAの数を選択できます。


delete.na 
解説 (0)

パフォーマンスが優先される場合は、オプションのparam cols =を使用して、 data.tableおよびna.omit()を使用します。

na.omit.data.tableは最速です私のベンチマーク(以下を参照)、すべての列または選択した列(OP質問パート2)。

data.tableを使用しない場合は、complete.cases()を使用します。

バニラ data.frameでは、complete.casesは[na .omit()](https:/www.rdocumentation.org/packages/3.4. na.omit.data.framecols =をサポートしていないことに注意してください。

ベンチマーク結果。

以下は、20の数値変数の100万の観測値と独立した5の観測値の想定データセットで、すべてまたは欠落観測値を選択するためのベース(青)、 dplyr(ピンク)、および data.table(黄色)メソッドの比較です。欠落する可能性の割合、およびパート2の4つの変数のサブセット。

結果は、特定のデータセットの長さ、幅、およびスパーシティに基づいて異なる場合があります。

y軸のログスケールに注意してください。

[。![ここに画像の説明を入力してください][1]][1]。

ベンチマークスクリプト。


#-------  Adjust these assumptions for your own use case  ------------
row_size   
解説 (0)

dplyrパッケージを使用すると、NAを次のようにフィルタリングできます。

dplyr::filter(df,  !is.na(columnname))
解説 (0)

これにより、少なくとも1つの非NA値を持つ行が返されます。


final[rowSums(is.na(final))
解説 (0)

最初の質問については、すべてのNAを取り除くために快適なコードがあります。 @Gregorをシンプルにしてくれてありがとう。

final[!(rowSums(is.na(final))),]

2番目の質問では、コードは以前のソリューションからの単なる代替です。

final[as.logical((rowSums(is.na(final))-5)),]

-5はデータの列数であることに注意してください。 rowSumsの合計が5になり、減算後にゼロになるため、これによりすべてのNAを持つ行が排除されます。 今回は、as.logicalが必要です。

解説 (1)

これにはサブセット関数を使用することもできます。


finalData
解説 (0)

私はシンセサイザーです:)。 ここで、回答を1つの関数に結合しました。


#' keep rows that have a certain number (range) of NAs anywhere/somewhere and delete others
#' @param df a data frame
#' @param col restrict to the columns where you would like to search for NA; eg, 3, c(3), 2:5, "place", c("place","age")
#' \cr default is NULL, search for all columns
#' @param n integer or vector, 0, c(3,5), number/range of NAs allowed.
#' \cr If a number, the exact number of NAs kept
#' \cr Range includes both ends 3
解説 (0)

データフレームとして「dat」を想定すると、期待出力はを使用して達成できます。

1。rowSums

> dat[!rowSums((is.na(dat))),]
             gene hsap mmul mmus rnor cfam
2 ENSG00000199674    0   2    2    2    2
6 ENSG00000221312    0   1    2    3    2

2。幸せ

> dat[!Reduce('|',lapply(dat,is.na)),]
             gene hsap mmul mmus rnor cfam
2 ENSG00000199674    0   2    2    2    2
6 ENSG00000221312    0   1    2    3    2
解説 (0)

delete.dirt 
解説 (0)

一般的でかなり読みやすいコードを生成する1つのアプローチは、dplyrパッケージで「filter」関数とそのバリアントを使用することです(「filter_all」、「filter_at」、「filter_if」)。

library(dplyr)

vars_to_check % 
  filter_at(.vars = vars(one_of(vars_to_check)),
            ~ !is.na(.))

# Filter all the columns to exclude NA
df %>% 
  filter_all(~ !is.na(.))

# Filter only numeric columns
df %>%
  filter_if(is.numeric,
            ~ !is.na(.))
解説 (0)

これは、この方法でよりエレガントに解決できると思います。

  m  1 NA NA 11 16 21
  #> 2  3  8 NA 18 23
  #> 3  5 10 15 20 NA
解説 (1)