我正在处理以下所示的数据框。
S.no tmp size
1 tmp1 100
2 tmp2, tmp3 200
3 tmp1, tmp2, tmp3 50
我想做的是绘制一个igraph图,其中每个tmp是一个顶点并接近边,每行中的tmp值将具有到该特定行中其余tmp值的边。节点大小与大小列成正比。节点tmp1的大小应为150(100 + 50),类似地,tmp2的节点大小应为250(200 + 50)。
我已经尝试过这种方法,将数据框设置为子集。
df <- table[3,2]
df # gives output as "tmp1, tmp2, tmp3"
class(df) # data frame
df <- gsub(", ",":",df)
df # gives output as "tmp1:tmp2:tmp3"
graph <- graph.formula(df:df) # graph.formula(:) to map every vertex
# to other vertices.
当我这样做时,我在图中得到一个节点,即以字符df为顶点。我已经尝试通过使用as.list(),as.character()强制将df强制转换为字符类型,列表类型,但是它没有用。
我已经浏览了图网站中的graph.data.frame()函数手册,但不了解如何以列方式输入顶点数据。
我在这里呆了几个小时,我是这里的新手。请帮忙!
这是您使用R友好格式的示例数据
df <- data.frame(
S.no = 1:3,
tmp = c("tmp1", "tmp2, tmp3", "tmp1, tmp2, tmp3"),
size = c(100, 200, 50), stringsAsFactors=F
)
首先,我想扩展tmp
列,以便每行有一个值
ddf<-with(df, do.call(rbind,
Map(cbind.data.frame, S.no=S.no, tmp=strsplit(tmp, ", "), size=size)
))
#
S.no tmp size
# 1 1 tmp1 100
# 2 2 tmp2 200
# 3 2 tmp3 200
# 4 3 tmp1 50
# 5 3 tmp2 50
# 6 3 tmp3 50
现在我可以根据S.no组号来组合边缘列表
el <- do.call(rbind, Filter(length, lapply(split(ddf$tmp, ddf$S.no), function(x)
if (length(x)>=2) t(combn(as.character(x),2)) )))
# [,1] [,2]
# [1,] "tmp2" "tmp3"
# [2,] "tmp1" "tmp2"
# [3,] "tmp1" "tmp3"
# [4,] "tmp2" "tmp3"
基本上,我们只是在寻找具有至少两个节点的组,然后将这些顶点的所有可能组合制成每个组的边列表,然后将所有内容绑定在一起。
最后,我们使用汇总来计算节点大小
vx <- aggregate(size~tmp, ddf, sum)
# tmp size
# 1 tmp1 150
# 2 tmp2 250
# 3 tmp3 250
现在我们以图形形式将其放在一起
gg <- graph.edgelist(el, FALSE)
V(gg)[as.character(vx[,1])]$size <- vx[,2]
plot(gg)
您可能需要将尺寸重新缩放为更合理的尺寸,以查看边缘
torange<-function(x, new.min=25, new.max=50) {
(x-min(x))/diff(range(x)) * (new.max-new.min) + new.min
}
V(gg)$size <- torange(V(gg)$size)
plot(gg)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句