用于在R中绘制iGraph的子集数据框

时间:2014-09-09 05:26:12

标签: r dataframe igraph subset

我正在处理如下所示的数据框架。

  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()函数手册,但无法理解如何 以列方式输入顶点数据。

我被困在这里几个小时,我是这里的新手。请帮忙!

2 个答案:

答案 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)

enter image description here

您可能希望将尺寸重新缩放到更合理的尺寸以查看边缘

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)

enter image description here

答案 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)