web-dev-qa-db-ja.com

値のベクトルに基づいてRのデータフレームの行をサブセット化するにはどうすればよいですか?

同じサイズであるはずの2つのデータセットがありますが、そうではありません。レポートに入力されるグラフからノイズを除去するために、AからBにない値をトリムする必要があります。逆も同様です。 (心配しないでください、このデータは完全に削除されません!)

私は次を読んだ:

しかし、私はまだこれを正しく動作させることができません。これが私のコードです:

bg2011missingFromBeg <- setdiff(x=eg2011$ID, y=bg2011$ID)
#attempt 1
eg2011cleaned <- subset(eg2011, ID != bg2011missingFromBeg)
#attempt 2
eg2011cleaned <- eg2011[!eg2011$ID %in% bg2011missingFromBeg]

最初の試行では、結果のsetdiffベクトルの最初の値が削除されます。 2回目の試行では、収量と扱いにくいエラーが発生します。

Error in `[.data.frame`(eg2012, !eg2012$ID %in% bg2012missingFromBeg) 
:  undefined columns selected
45
Zelbinian

これにより、必要なものが得られます。

eg2011cleaned <- eg2011[!eg2011$ID %in% bg2011missingFromBeg, ]

2回目の試行でのエラーは、,を忘れたためです

一般的に、便宜上、仕様はobject[index]が2d objectの列をサブセットします。行をサブセット化し、すべての列を保持する場合は、object[index_rows, index_columns]仕様を使用する必要がありますが、index_colsは空白のままにできます。デフォルトではすべての列が使用されます。

ただし、列のサブセットではなく行のサブセットを取得することを示すには、,を含める必要があります。

66
adibender

本当に両方のデータフレームに存在するインデックスによって各データフレームをサブセット化するだけの場合は、次のように 'match'関数を使用してこれを行うことができます。

data_A[match(data_B$index, data_A$index, nomatch=0),]
data_B[match(data_A$index, data_B$index, nomatch=0),]

ただし、これは次と同じです。

data_A[data_A$index %in% data_B$index,]
data_B[data_B$index %in% data_A$index,]

デモは次のとおりです。

# Set seed for reproducibility.
set.seed(1)

# Create two sample data sets.
data_A <- data.frame(index=sample(1:200, 90, rep=FALSE), value=runif(90))
data_B <- data.frame(index=sample(1:200, 120, rep=FALSE), value=runif(120))

# Subset data of each data frame by the index in the other.
t_A <- data_A[match(data_B$index, data_A$index, nomatch=0),]
t_B <- data_B[match(data_A$index, data_B$index, nomatch=0),]

# Make sure they match.
data.frame(t_A[order(t_A$index),], t_B[order(t_B$index),])[1:20,]

#    index     value index.1    value.1
# 27     3 0.7155661       3 0.65887761
# 10    12 0.6049333      12 0.14362694
# 88    14 0.7410786      14 0.42021589
# 56    15 0.4525708      15 0.78101754
# 38    18 0.2075451      18 0.70277874
# 24    23 0.4314737      23 0.78218212
# 34    32 0.1734423      32 0.85508236
# 22    38 0.7317925      38 0.56426384
# 84    39 0.3913593      39 0.09485786
# 5     40 0.7789147      40 0.31248966
# 74    43 0.7799849      43 0.10910096
# 71    45 0.2847905      45 0.26787813
# 57    46 0.1751268      46 0.17719454
# 25    48 0.1482116      48 0.99607737
# 81    53 0.6304141      53 0.26721208
# 60    58 0.8645449      58 0.96920881
# 30    59 0.6401010      59 0.67371223
# 75    61 0.8806190      61 0.69882454
# 63    64 0.3287773      64 0.36918946
# 19    70 0.9240745      70 0.11350771
16
Dinre

本当に人間が理解できるの例(%in%を初めて使用するので)、2つのデータフレームを比較し、特定の列に等しい値を含む行のみを保持する方法:

# Set seed for reproducibility.
set.seed(1)

# Create two sample data frames.
data_A <- data.frame(id=c(1,2,3), value=c(1,2,3))
data_B <- data.frame(id=c(1,2,3,4), value=c(5,6,7,8))

# compare data frames by specific columns and keep only 
# the rows with equal values 
data_A[data_A$id %in% data_B$id,]   # will keep data in data_A
data_B[data_B$id %in% data_A$id,]   # will keep data in data_b

結果:

> data_A[data_A$id %in% data_B$id,]
  id value
1  1     1
2  2     2
3  3     3

> data_B[data_B$id %in% data_A$id,]
  id value
1  1     5
2  2     6
3  3     7
3
maycca

元の投稿へのコメントによると、マージ/結合はこの問題に適しています。特に、inner joinは両方のデータフレームに存在する値のみを返すため、setdiffステートメントは不要です。

Dinreの例のデータを使用する:

基数R:

cleanedA <- merge(data_A, data_B[, "index"], by = 1, sort = FALSE)
cleanedB <- merge(data_B, data_A[, "index"], by = 1, sort = FALSE)

dplyrパッケージを使用:

library(dplyr)
cleanedA <- inner_join(data_A, data_B %>% select(index))
cleanedB <- inner_join(data_B, data_A %>% select(index))

それぞれが独自の変数のみを含む2つの個別のテーブルとしてデータを保持するために、これにより、結合前に不要なテーブルがインデックス変数のみにサブセット化されます。その後、結果のテーブルに新しい変数は追加されません。

2
Sam Firke