7

R でのデータ操作の一般的なタスクの 1 つは、特定の基準に一致する行を削除してデータフレームをサブセット化することです。ただし、R でこれを行う簡単な方法は、論理的に一貫性がなく、未経験者 (私のような) にとっては危険ですらあります。

データフレームがあり、「G1」処理に属する行を除外したいとしましょう:

Treatment=c("G1","G1","G1","G1","G1","G1","G2","G2","G2","G2","G2",
"G2","G3","G3","G3","G3","G3","G3")
Vals=c(runif(6),runif(6)+0.9,runif(6)-0.3)
data=data.frame(Treatment)
data=cbind(data, Vals)  

予想どおり、以下のコードは、最初の行の条件に一致するデータフレーム行を削除します

to_del=which(data$Treatment=="G1")
new_data=data[-to_del,]
new_data

ただし、予想に反して、「which」コマンドで一致する行が見つからない場合、このアプローチを使用すると、このコードはすべての行をそのままにするのではなく、すべての行を削除します。

to_del=which(data$Treatment=="G4")
new_data=data[-to_del,]
new_data

上記のコードでは、行が残っていないデータ フレームが生成されますが、これは意味がありません (つまり、R は私の削除基準に一致する行を見つけられなかったため、すべての行を削除しました)。私の回避策は仕事をしますが、これらの条件文をすべて使わずにこれを行う簡単な方法があると思います

###WORKAROUND
to_del=which(data$Treatment=="G4") #no G4 treatment in this particular data frame
if (length(to_del)>0){
  new_data=data[-to_del,]  
}else{
  new_data=data
}
new_data

指定された条件に一致する行がない場合でも機能する、これを行う簡単な方法はありますか?

4

4 に答える 4

6

の使用に関する一般的な問題に遭遇しましたwhich!=代わりに使用してください。

new_data <- data[data$Treatment!="G4",]

問題は、すべての要素が である場合にwhich返されることです。ゼロによるサブセット化も返すため、これは返されたとしても問題になります。integer(0)FALSEwhich0integer(0)

R> # subsetting by zero (positive or negative)
R> (1:3)[0]  # same as (1:3)[-0]
integer(0)

次のようにサブセット化すると、問題が発生することもありますNA

R> # subsetting by NA
R> (1:3)[NA]
[1] NA NA NA
于 2013-02-15T21:40:33.537 に答える
3

data.tableサブセット化には、より直感的で短く、大きなデータセットでより高速に実行されるため、使用するのが好きです。

library(data.table)
data.dt<-as.data.table(data)
setkey(data.dt, Treatment)

data.dt[!"G1",]
##     Treatment        Vals
##  1:        G2  0.90264622
##  2:        G2  1.47842130
##  3:        G2  1.52494735
##  4:        G2  1.46373958
##  5:        G2  1.12850658
##  6:        G2  1.46705561
##  7:        G3  0.58451869
##  8:        G3 -0.20231228
##  9:        G3  0.52519475
## 10:        G3  0.62956475
## 11:        G3 -0.06655426
## 12:        G3  0.56814703

data.dt[!"G4",]
##    Treatment        Vals
## 1         G1  0.93411692
## 2         G1  0.60153972
## 3         G1  0.28147464
## 4         G1  0.97264924
## 5         G1  0.50804831
## 6         G1  0.48273876
## 7         G2  0.90264622
## 8         G2  1.47842130
## 9         G2  1.52494735
## 10        G2  1.46373958
## 11        G2  1.12850658
## 12        G2  1.46705561
## 13        G3  0.58451869
## 14        G3 -0.20231228
## 15        G3  0.52519475
## 16        G3  0.62956475
## 17        G3 -0.06655426
## 18        G3  0.56814703

キーとして設定されていない列をサブセット化する場合は、サブセットで列名を使用する必要があることに注意してください(例data.dt[Vals<0,]) 。

data.tableの作成者は、削除されていないすべての行を新しいテーブルにコピーしてから元のテーブルを削除するのではなく、元のテーブルから行を直接削除する方法に取り組んでいる可能性があると思います。これは、メモリの制限に直面しているときに非常に役立ちます。

于 2013-02-16T14:03:31.213 に答える
3

なぜ使用しないのsubsetですか?

subset(data,  ! rownames(data) %in% to_del )

(とにかく、例では行名に暗黙的に一致していましdata[-to_del, ]た。)もちろん、それが機能したら、単に「[」を使用することに戻ることができます。

data[  ! rownames(data) %in% to_del , ]
于 2013-02-15T22:09:39.340 に答える
2

問題は、DELETEする行を選択していないことです。 KEEP する行を選択しています。お気づきのように、これらの概念は頻繁に入れ替えることができますが、問題が発生することもあります。

具体的には、使用whichすると、Rに「このベクトルのどの要素が真か」を尋ねます。ただし、何も見つからない場合は、 を返すことでこれを示しますinteger(0)

Integer(0) は実際の数値ではないため、Integer(0) のマイナスを取っても Integer(0) になります。

ただし、単純にフィルタリングに使用する場合は、 which を使用する必要はありません。

代わりに、渡すステートメントを取得しwhichて、フィルターとして直接 に渡します data[..]。整数ベクトルと同様に、論理ベクトルをインデックスとして使用できることを思い出してください。

于 2013-02-15T21:44:16.020 に答える