2017-09-05 42 views
7

我在基於行和列中值的互惠性對數據框架進行子集時遇到了問題。按行列可互換子集

下面是一個例子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

你錯誤地使用了字倒數。 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的解決方案雖然慢) :

merge(rating.data,setNames(rating.data,rev(names(rating.data)))) 

保持第二個解決方案靈活機智^ h您的附加列:

精神
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

類似akrun的方法,rbind的data.frame與逆轉列的副本。從底部開始查找重複項,然後將原始data.frame中的行返回TRUE。用[seq_len(nrow(rating.data))]子集這個邏輯向量來返回一個適當長度的向量到[,以便在行上進行子集化。

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

您還可以使用pminpmax協助分組,然後在具有多個條目的所有組篩選,即

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