2017-09-05 3 views
7

行と列の値の相反関係に基づいてdata.frameをサブセット化する際に問題があります。ここで行と列の相反関係によるサブセット

は、問題を説明するための例のDFである:

rater <- c(21, 23, 26, 24) 
ratee <- c(24, 21, 23, 21) 
rating.data <- data.frame(rater, ratee) 

出力:

rater ratee 
1 21 24 
2 23 21 
3 26 23 
4 24 21 

私は唯一の逆数の値を持つ行を保つことによって、このDFをサブセットしたいと思います。

結果のサブセットは、次のようになります。

rater ratee 
1 21 24 
4 24 21 

任意の考えをいただければ幸いです!

+0

あなたは間違って単語reciprocalを使用しています。 1/xはxの逆数です。 –

+0

対称行列になりたいですか? –

+0

https://stackoverflow.com/questions/28574006/unique-rows-considering-two-columns-in-r-without-orderリンクを確認してください – Wen

答えて

6

を使用することができます。

library(dplyr) 
rating.data %>% inner_join(.,.,by=c("rater" = "ratee","ratee"="rater")) 

またはこの、それは(akrunのソリューションよりも遅くても)自分の小さな例に二回高速です何らかの理由:

第2の解決策を柔軟に保つ時間あなたの追加の列:akrunの方法とその精神において同様

merge(rating.data,setNames(rating.data[,c("rater","ratee")],c("ratee","rater"))) 
+0

ありがとう!これは実際に私が探していたもので、私は残りのdfを失いたくないからです。これにより、私が気にしている列を指定することができます。私の心を読んでくれてありがとう! – SeekingData

+0

akrunのソリューションは簡単に適合させることができますが、 'rating.data [、c(" rater "、" ratee ")]'を最初の行に入力すれば、問題があれば速くなるかもしれません。 –

8

我々が行でソートして、別の可能性duplicated

m1 <- t(apply(rating.data, 1, sort)) 
rating.data[duplicated(m1)|duplicated(m1, fromLast = TRUE),] 
# rater ratee 
#1 21 24 
#4 24 21 
+1

これは素晴らしいことです!私は問題のために複製されたを使用する方法を考えようとしています。これはうまくいく!ありがとうございました! – SeekingData

+1

@SeekingDataこの回答が役に立ったら、それを受け入れることができます:) – Wen

+0

私は両方を受け入れることができたらいいと思います。ありがとう、Akrun! – SeekingData

2
library(data.table) 
N=10#number of rows 
dt1<-data.table(a=1:N,b=sample(N))#create the data.table that holds the info 

dt1[,d:=ifelse(a<b,paste0(a,"_",b),paste0(b,"_",a))]#create unique key per pair respecting the rule "min_max" 
setkey(dt1,d)#setting the key 
dt1[dt1[,.N,d][N!=1],.(a,b)] #keep only the pairs that appear more than once 
1

、列のコピーへのrbind data.frameが逆転しました。下から順に重複を見つけ、元のdata.frameの行に対してTRUEを返します。この論理ベクトルを[seq_len(nrow(rating.data))]にサブセット化して、適切な長さのベクトルを[に戻して、行のサブセットを作成します。あなたはまた、複数のエントリを持つすべてのグループにフィルタを適用後、グループ化を支援するためにpminpmaxを使用することができ

rating.data[duplicated(rbind(rating.data, 
          unname(unclass(rating.data[2:1]))), 
         fromLast=TRUE)[seq_len(nrow(rating.data))],] 
    rater ratee 
1 21 24 
4 24 21 
2

、すなわち

与え
library(dplyr) 

df %>% 
group_by(grp = paste0(pmin(rater, ratee), pmax(rater, ratee))) %>% 
filter(n() > 1) %>% 
ungroup() %>% 
select(-grp) 

# A tibble: 2 x 2 
    rater ratee 
    <dbl> <dbl> 
1 21 24 
2 24 21 
+1

私は 'pmin/pmax'アプローチについて考えました。それはより速くなるでしょう – akrun

関連する問題