[英]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.