如何基于其他列分配公共id/id';他在R吗?
我有一个数据框,看起来像这样:如何基于其他列分配公共id/id';他在R吗?,r,algorithm,functional-programming,network-programming,R,Algorithm,Functional Programming,Network Programming,我有一个数据框,看起来像这样: 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 现在,我想根据以下逻辑创建一个新列“output”: 第一级关系:即使单个id匹配(NA不计算在内)的所有实体都必须分配相同
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
现在,我想根据以下逻辑创建一个新列“output”:
第一级关系:即使单个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
)
现在,如果我们想将其分配回原始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
dd$id4谢谢。这真的很有帮助。构建边缘列表连接时的一个小添加。我们希望连接id1和id3,以防id2列中有任何NA。我考虑过这个问题,但我想不出一个例子,说明需要这样做,或者产生了不同的结果。你有这样的例子吗?id2中是否有NA,但id1和id3中都有值?正确。在实际数据集中,我在id2中有NA,但在id1和id3中有值。
vx <- na.omit(unique(unlist(dd[, 2:4])))
library(igraph)
gg<-graph.data.frame(el, vertices=vx, directed=F)
plot(gg)
newid <- data.frame(
vertex=V(gg)$name,
grp=clusters(gg)$membership
)
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