web-dev-qa-db-ja.com

RのNA値のみを使用してdata.frameの行を識別する

34個の順序変数とNA変数の15,000個の観測値を持つdata.frameがあります。マーケットセグメンテーション調査のためにクラスタリングを実行しており、NAsのみを削除した行が必要です。 userIDを取り出した後、クラスタリングの前にNAsのみで2099行を省略するようにというエラーメッセージが表示されました。

すべてのNA値を持つ行を削除するためのリンクを見つけましたが、2099行のどれがすべてNA値を持つかを識別する必要があります。ここに、すべてのNA値を持つ行を削除するディスカッションのリンクがあります: data.frame内のNAを持つ行を削除する

これは、6つの変数からの最初の5つの観測値のサンプルです。

> head(Store2df, n=5)
  RowNo      Age Gender HouseholdIncome MaritalStatus PresenceofChildren
1     1     <NA>   Male            <NA>          <NA>               <NA>
2     2    45-54 Female            <NA>          <NA>               <NA>
3     3     <NA>   <NA>            <NA>          <NA>               <NA>
4     4     <NA>   <NA>            <NA>          <NA>               <NA>
5     5    45-54 Female        75k-100k       Married                Yes
#Making a vector
> Vector1 <- Store2df$RowNo 
#Taking out RowNo column
> Store2df$RowNo <- NULL

EDIT:結果をオブジェクトに入れましたが、コードが余分な列を作成していることがわかりました。 RStudioの環境をクリックすると、row.namesという追加の列が作成され、各行に元の行名のラベルが付けられました。数千行が削除され、新しい列には古い行番号で新しい行のラベルが付けられました。ただし、新しいオブジェクトの先頭を見ると、行ラベルが表示されませんでした。 row.namesラベルが環境に表示されるのに、頭を表示したときに表示されないのはなぜですか?

#Remove all rows with only NA values
> Store2df <- Store2[!!rowSums(!is.na(Store2)),]
#View head of store2df
> head(Store2df)
    Age Gender HouseholdIncome MaritalStatus PresenceofChildren
1  <NA>   Male            <NA>          <NA>               <NA>
2 45-54 Female            <NA>          <NA>               <NA>
5 45-54 Female        75k-100k       Married                Yes
6 25-34   Male        75k-100k       Married                 No
7 35-44 Female       125k-150k       Married                Yes
8 55-64   Male        75k-100k       Married                 No

編集2:ユーザー数を追跡するために行番号/ userID列に入力しました。すべてのNAsを削除する操作を実行するために、最初の列を取り出しました。次に、削除したユーザーを追跡する必要があります。すべてのNA値を持つ2000を超える行のリストがありますが、各行に手動でインデックスを作成したくありません。

質問:不足しているデータが対応する電子メールを削除するにはどうすればよいですか?

> #First six rows of the column RowNo
> head(Store2df$RowNo)
[1] 1 2 3 4 5 6

Store2df data.frameで2099行を削除し、RowNoを含めたい。これは、Store2df data.frameRowNoなしですべて空である行を識別するスクリプトです。

> which(rowSums(is.na(Store2df))==ncol(Store2df))

最初の6行を表示すると、行番号3と4が削除されます。

> head(Store2df$RowNo)
[1] 1 2 5 6 7 8

完了したい4つのステップがあります:

1)Store2df data.frameRowNo列を取り出し、別のベクターとして保存します

2)Store2df data.frameのすべてのNA値を持つ行を削除します

3)Store2new1 vectorのStore2dfdata.frameと同じ行を削除します

4)vectordata.framedata.frameと一致するvectorと組み合わせます

9
Scott Davis
_ which(rowSums(is.na(Store2))==ncol(Store2))
 #3 4 
 #3 4 
_

または

_ which(Reduce(`&`,as.data.frame(is.na(Store2))))
 #[1] 3 4
_

または

_ which(!rowSums(!is.na(Store2)))  
 #3 4 
 #3 4 
_

データ

_ Store2 <- structure(list(Age = c(NA, "45-54", NA, NA, "45-54"), Gender = c("Male", 
 "Female", NA, NA, "Female"), HouseholdIncome = c(NA, NA, NA, 
  NA, "75k-100k"), MaritalStatus = c(NA, NA, NA, NA, "Married"), 
PresenceofChildren = c(NA, NA, NA, NA, "Yes"), HomeOwnerStatus = c(NA, 
NA, NA, NA, "Own"), HomeMarketValue = c(NA, NA, NA, NA, "150k-200k"
)), .Names = c("Age", "Gender", "HouseholdIncome", "MaritalStatus", 
"PresenceofChildren", "HomeOwnerStatus", "HomeMarketValue"), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5"))
_

更新

すべてのNAsを含む行を削除するには

_  Store2[!!rowSums(!is.na(Store2)),]
  #   Age Gender HouseholdIncome MaritalStatus PresenceofChildren HomeOwnerStatus
  #1  <NA>   Male            <NA>          <NA>               <NA>            <NA>
  #2 45-54 Female            <NA>          <NA>               <NA>            <NA>
  #5 45-54 Female        75k-100k       Married                Yes             Own
   #HomeMarketValue
  #1            <NA>
  #2            <NA>
  #5       150k-200k
_
  • is.na(Store2)は、欠落している要素またはNAの論理インデックスを提供します
  • _!_は論理インデックスを無効にします。つまり、TRUEFALSEになり、その逆も同様です。
  • 上記のコードのrowSumsは、各行の_not NA_である要素の合計を示します。

    _    rowSums(!is.na(Store2))
        #   1 2 3 4 5 
        #   1 2 0 0 7  # 3rd and 4th row have `0 non NA` values
    _
  • _!_上記を否定する

    _    !rowSums(!is.na(Store2))
        # 1     2     3     4     5 
        #FALSE FALSE  TRUE  TRUE FALSE 
    _
  • _all NA's_または_0 non NAs_である行を削除したかったのです。だから_!_再び

    _    !!rowSums(!is.na(Store2))
        #1     2     3     4     5 
        #TRUE  TRUE FALSE FALSE  TRUE 
    _
  • 上記の論理インデックスを使用したサブセット

Update2

2つのrowNoがある場合、つまり、1つはNA行を削除する前に別々に保存し、もう1つはNAを削除した後です。

_   RowNo1 <- 1:6
   RowNo2 <- c(1,2,5,6)
   RowNo1 %in% RowNo2
   #[1]  TRUE  TRUE FALSE FALSE  TRUE  TRUE
   RowNo1[RowNo1 %in% RowNo2]
   #[1] 1 2 5 6
_

Update3

新しいリクエストで、もう一度試してみましょう。

_    Store2 <- structure(list(RowNo = 1:5, Age = c(NA, "45-54", NA, NA, "45-54"
    ), Gender = c("Male", "Female", NA, NA, "Female"), HouseholdIncome = c(NA, 
    NA, NA, NA, "75k-100k"), MaritalStatus = c(NA, NA, NA, NA, "Married"
   ), PresenceofChildren = c(NA, NA, NA, NA, "Yes")), .Names = c("RowNo", 
   "Age", "Gender", "HouseholdIncome", "MaritalStatus", "PresenceofChildren"
   ), class = "data.frame", row.names = c("1", "2", "3", "4", "5"
   ))
_

最初の一歩

RowNoを個別のベクトルとして保存する(なぜこれが必要なのかわかりません)

_  Store2new1 <- Store2$RowNo
_

第二段階

_Store2_ data.frame内のすべてのNA値を含む行を削除し、_Store2df_として保存します

_   Store2df <- Store2[!!rowSums(!is.na(Store2[,-1])),] #Here you already get the new dataset with `RowNo` column

   Store2df
   #RowNo   Age Gender HouseholdIncome MaritalStatus PresenceofChildren
   #1     1  <NA>   Male            <NA>          <NA>               <NA>
   #2     2 45-54 Female            <NA>          <NA>               <NA>
   #5     5 45-54 Female        75k-100k       Married                Yes
_

3番目のステップ

Store2dfdata.frameと同じStore2new1ベクトルの行を削除します

_   Store2new2 <- Store2new1[Store2new1 %in% Store2df$RowNo]
   Store2new1[Store2new1 %in% Store2df$RowNo]
   #[1] 1 2 5
_

4番目のステップ

投稿からは明らかではないが、さらに行を削除したい場合を除いて、4番目または3番目のステップは実際には必要ないと思います。

12
akrun

@akrunによって提供された回答に投稿されたStore2サンプルデータを使用する

which(apply(Store2, 1, function(x) all(is.na(x))))
#3 4 
#3 4 

または、akrunの答えと同様に:

which(rowSums(!is.na(Store2))==0)
#3 4 
#3 4 
4
Jota