我正在处理如下所示的数据框架。
S.no tmp size
1 tmp1 100
2 tmp2, tmp3 200
3 tmp1, tmp2, tmp3 50
我想要做的是绘制一个igraph图,其中每个tmp是一个顶点并且到达边缘,每一行中的tmp值将具有该特定行中tmp值的其余部分的边缘。 节点大小与size列成比例。 节点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()函数手册,但无法理解如何 以列方式输入顶点数据。
我被困在这里几个小时,我是这里的新手。请帮忙!
答案 0 :(得分:0)
以下是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)
答案 1 :(得分:0)
您也可以使用cSplit
library(data.table)
library(devtools)
source_gist(11380733)
df <- data.frame(
S.no = 1:3,
tmp = c("tmp1", "tmp2, tmp3", "tmp1, tmp2, tmp3"),
size = c(100, 200, 50), stringsAsFactors=F
)
ddf <- cSplit(df, "tmp", ", ", "long")
el1 <- as.matrix(ddf[,.SD[.N>=2], by=S.no][,
{tmp <- combn(tmp,2)
list(tmp[1,], tmp[2,])},
by=S.no][,S.no:=NULL])
vx <- as.data.frame(ddf[, list(size=sum(size)), by=tmp])
gg <- graph.edgelist(el1, FALSE)
V(gg)[as.character(vx[,1])]$size <- vx[,2]
plot(gg)