我正在尝试在igraph
中进行网络分析,但考虑到不同的列数,我在将数据集转换为边缘列表(带权重)方面存在一些问题。
数据集如下所示(df1
)(当然要大得多):首先是主操作符id(主操作符也可以是伙伴,反之亦然,因此ID在边缘保持不变列表)挑战是合作伙伴的数量不同(从0到40)并且必须考虑每个互动(不仅仅是#34; IdMain到IdPartnerX")。
IdMain IdPartner1 IdPartner2 IdPartner3 IdPartner4 .....
1 4 3 7 6
2 3 1 NA NA
3 1 4 2 NA
4 9 6 3 NA
.
.
我已经获得了有用的提示,可以使用reshape来执行此操作,例如:
data_melt <- reshape2::melt(data, id.vars = "IdMain")
edgelist <- data_melt[!is.na(data_melt$value), c("IdMain", "value")]
然而,这只会创造一个“定向”的对象。 edgelist(从Main到Partners)。我需要的是下面的内容,其中记录了每次互动。
Id1 Id2
1 4
1 3
1 7
1 6
4 3
4 7
4 6
3 7
etc
有没有人提示最好的方法是什么?我也查看了igraph
库,但无法找到执行此操作的函数。
答案 0 :(得分:1)
不需要重塑(2)和熔化等。您只需要抓取每个列对的组合,然后将它们绑定在一起。
x <- read.table(text="IdMain IdPartner1 IdPartner2 IdPartner3 IdPartner4
1 4 3 7 6
2 3 1 NA NA
3 1 4 2 NA
4 9 6 3 NA", header=TRUE)
idx <- t(combn(seq_along(x), 2))
edgelist <- lapply(1:nrow(idx), function(i) x[, c(idx[i, 1], idx[i, 2])])
edgelist <- lapply(edgelist, setNames, c("ID1","ID2"))
edgelist <- do.call(rbind, edgelist)
edgelist <- edgelist[rowSums(is.na(edgelist))==0, ]
edgelist
# ID1 ID2
# 1 1 4
# 2 2 3
# 3 3 1
# 4 4 9
# 5 1 3
# 6 2 1
# 7 3 4
# 8 4 6
# 9 1 7
# 11 3 2
# 12 4 3
# 13 1 6
# 17 4 3
# 18 3 1
# 19 1 4
# 20 9 6
# 21 4 7
# 23 1 2
# 24 9 3
# 25 4 6
# 29 3 7 <--
# 31 4 2
# 32 6 3
# 33 3 6 <--
# 37 7 6 <--
答案 1 :(得分:1)
使用以下数据。您可以使用apply
和combn
来实现您的目标。这将返回一个列表矩阵,其中包含data.frame
myPairs <- apply(t(dat), 2, function(x) t(combn(x[!is.na(x)], 2)))
请注意,apply的输出可能很挑剔,此处必须至少有一行带有NA,以便apply
返回列表而不是矩阵。
如果您想在最后使用data.frame,请使用do.call
和rbind
将矩阵放在一起,然后使用data.frame
和setNames
进行对象强制,并使用添加名称。
setNames(data.frame(do.call(rbind, myPairs)), c("Id1", "Id2"))
Id1 Id2
1 1 4
2 1 3
3 1 7
4 1 6
5 4 3
6 4 7
7 4 6
8 3 7
9 3 6
10 7 6
11 2 3
12 2 1
13 3 1
14 3 1
15 3 4
16 3 2
17 1 4
18 1 2
19 4 2
20 4 9
21 4 6
22 4 3
23 9 6
24 9 3
25 6 3
数据强>
dat <-
structure(list(IdMain = 1:4, IdPartner1 = c(4L, 3L, 1L, 9L),
IdPartner2 = c(3L, 1L, 4L, 6L), IdPartner3 = c(7L, NA, 2L,
3L), IdPartner4 = c(6L, NA, NA, NA)), .Names = c("IdMain",
"IdPartner1", "IdPartner2", "IdPartner3", "IdPartner4"),
class = "data.frame", row.names = c(NA, -4L))