簡體   English   中英

如何基於R中的其他列/ ID分配公共ID?

[英]How to assign a common id based on other columns/id's in R?

我有一個看起來像這樣的數據框:

Sn  id1 id2 id3    
1   abc 123  NA   
2   xyz 111 vvv  
3   qwe 222 vvv    
4   rty  NA  NA    
5   abc  NA  NA    
6   ddd 234  NA   
7   sss 222  NA   
8   aaa  NA  NA

現在,我想根據以下邏輯創建一個新的列“輸出”:

關系的第一級:即使是單個id匹配( NA不計算在內)的所有實體也必須分配相同的id

第二級關系:如果2連接到3且3連接到7,則2,3和7都必須具有相同的id

因此,這里的輸出將是:

Sn  id1 id2 id3 id4    
1   abc 123 NA  100001   
2   xyz 111 vvv 100002  
3   qwe 222 vvv 100002  
4   rty NA  NA  100003    
5   abc NA  NA  100001    
6   ddd 234 NA  100004    
7   sss 222 NA  100002   
8   aaa NA  NA  100005

請讓我知道最簡單的方法是什么。 任何想法都歡迎。

我目前正在考慮創建一個8 * 8矩陣,該矩陣將包含一個標志以指示兩個實體(行)之間是否存在匹配。

我喜歡使用igraph執行類似的任務(具有“連接的”節點)。 因此,如果我們從復制/粘貼友好型data.frame格式的示例數據開始

dd <- data.frame(
    Sn = 1:8, 
    id1 = c("abc", "xyz", "qwe", "rty", "abc", "ddd", "sss", "aaa"), 
    id2 = c(123L, 111L, 222L, NA, NA, 234L, 222L, NA), 
    id3 = c(NA, "vvv", "vvv", NA, NA, NA, NA, NA),
    stringsAsFactors=F
)

現在的第一步是在給定行的所有節點上建立連接的邊緣列表

el <- rbind(
    setNames(dd[,2:3], c("A","B")),
    setNames(dd[,3:4], c("A","B"))
)
el <- el[complete.cases(el),]    #(ignore NA)

而且,我們還需要所有文字名稱的唯一列表

vx <- na.omit(unique(unlist(dd[, 2:4])))

現在我們可以創建一個圖形對象

library(igraph)
gg<-graph.data.frame(el, vertices=vx, directed=F)
plot(gg)

在此處輸入圖片說明

然后,我們可以使用cluster()函數查找不同的組並獲取每個頂點的組號

newid <- data.frame(
    vertex=V(gg)$name, 
    grp=clusters(gg)$membership
)

現在,如果我們要將其分配回原始的data.frame,我們實際上只需要在id1列上進行匹配即可。

dd$id4 <- newid$grp[match(dd$id1, newid$vertex)]+100000
dd

#   Sn id1 id2  id3    id4
# 1  1 abc 123 <NA> 100001
# 2  2 xyz 111  vvv 100002
# 3  3 qwe 222  vvv 100002
# 4  4 rty  NA <NA> 100003
# 5  5 abc  NA <NA> 100001
# 6  6 ddd 234 <NA> 100004
# 7  7 sss 222 <NA> 100002
# 8  8 aaa  NA <NA> 100005

我們會得到您想要的結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM