2015-09-25 36 views
2

我有一個看起來像這樣的數據幀:打開有序對進入無序對在數據幀與dplyr

library(dplyr) 
df <- data_frame(doc.x = c("a", "b", "c", "d"), 
       doc.y = c("b", "a", "d", "c")) 

這樣df是:

Source: local data frame [4 x 2] 

    doc.x doc.y 
    (chr) (chr) 
1  a  b 
2  b  a 
3  c  d 
4  d  c 

這是排序的列表對,ad,還有da等等。什麼是類似dplyr的方式來返回這個數據框中的無序對的列表?即

doc.x doc.y 
    (chr) (chr) 
1  a  b 
2  c  d 
+1

'切片(DF,1:2)' – Jaap

+2

第一代碼塊不匹配所述第二和第三。 – Backlin

+0

@Backlin:謝謝,我修復了它。 –

回答

7

使用pminpmax到對按字母順序即依次排序,(B, a)變成(a,b),然後過濾掉所有的重複。

df %>% 
    mutate(dx = pmin(doc.x, doc.y), dy = pmax(doc.x, doc.y)) %>% 
    distinct(dx, dy) %>% 
    select(-dx, -dy) 
doc.x doc.y 
    (chr) (chr) 
1  a  b 
2  c  d 
+1

'df%>%distinct(dn = pmin(doc.x,doc.y),up = pmax(doc。 x,doc.y))%>%select(-up,-dn)',因爲'distinct'用於重複數據刪除。 – Frank

+0

油滑 - 我喜歡你如何使用'pmin'和'pmax' – Whitebeard

2
使用 data.table

另一種方法:

df <- data.frame(doc.x = c("a", "b", "c", "d"), 
       doc.y = c("b", "a", "d", "c"), stringsAsFactors = F) 


library(data.table) 
setDT(df) 
df[, row := 1:nrow(df)] 
df <- df[, list(Left = max(doc.x,doc.y),Right = min(doc.x,doc.y)), by = row] 
df <- df[, list(Left,Right)] 
unique(df) 
    Left Right 
1: b  a 
2: d  c 
+1

您應該使用'row:= 1:nrow(df)',因爲'length(df)'會爲您提供列數而不是行數。 – Backlin

+0

@akrun他正在尋找無序對,所以'ba'等同於'ab' – Chris

+0

@Backlin編輯 – Chris

1

使用dplyr

# make character columns into factors 
df <- as.data.frame(unclass(df)) 
df$x.lvl <- levels(df$doc.x) 
df$y.lvl <- levels(df$doc.y) 

# find unique pairs 
res <- df %>% 
    group_by(doc.x) %>% 
    transform(x.lvl = order(doc.x), 
    y.lvl = order(doc.y)) %>% 
    transform(pair = ifelse(x.lvl < y.lvl, 
     paste(doc.x, doc.y, sep=","), paste(doc.y, doc.x, sep=","))) %>% 
    .$pair %>% 
    unique 

唯一對

res 
[1] a,b c,d 
Levels: a,b c,d 

編輯

通過Backlin的解決方案的啓發,在基礎R

unique(with(df, paste(pmin(doc.x, doc.y), pmax(doc.x, doc.y), sep=",")) 
[1] "a,b" "c,d" 

或者在一個data.frame存儲

unique(with(df, data.frame(lvl1=pmin(doc.x, doc.y), lvl2=pmax(doc.x, doc.y)))) 

    lvl1 lvl2 
1 a b 
3 c d 
相關問題