首页 文章

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

提问于
浏览
0

我正在研究下面显示的数据框架 .

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) .

我试过这种方式,Subset数据框 .

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

    这是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

  • 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)
    

相关问题