【问题标题】:From dataframe to vertex/edge array从数据框到顶点/边数组
【发布时间】:2012-09-11 04:40:22
【问题描述】:

我有数据框

test <- structure(list(
     y2002 = c("freshman","freshman","freshman","sophomore","sophomore","senior"),
     y2003 = c("freshman","junior","junior","sophomore","sophomore","senior"),
     y2004 = c("junior","sophomore","sophomore","senior","senior",NA),
     y2005 = c("senior","senior","senior",NA, NA, NA)), 
              .Names = c("2002","2003","2004","2005"),
              row.names = c(c(1:6)),
              class = "data.frame")
> test
       2002      2003      2004   2005
1  freshman  freshman    junior senior
2  freshman    junior sophomore senior
3  freshman    junior sophomore senior
4 sophomore sophomore    senior   <NA>
5 sophomore sophomore    senior   <NA>
6    senior    senior      <NA>   <NA>

并且我需要在学生类别连续几年发生变化时创建一个顶点/边列表(用于 igraph),而在没有变化时忽略,如

testvertices <- structure(list(
 vertex = 
  c("freshman","junior", "freshman","junior","sophomore","freshman",
    "junior","sophomore","sophomore","sophomore"),
 edge = 
  c("junior","senior","junior","sophomore","senior","junior",
    "sophomore","senior","senior","senior"),
 id =
  c("1","1","2","2","2","3","3","3","4","5")),
                       .Names = c("vertex","edge", "id"),
                       row.names = c(1:10),
                       class = "data.frame")
> testvertices
      vertex      edge id
1   freshman    junior  1
2     junior    senior  1
3   freshman    junior  2
4     junior sophomore  2
5  sophomore    senior  2
6   freshman    junior  3
7     junior sophomore  3
8  sophomore    senior  3
9  sophomore    senior  4
10 sophomore    senior  5

此时我忽略了 id,我的图表应该按计数加权边缘(即新生 -> 初级 =3)。这个想法是制作一个树形图。我知道它在主要的 munging 点旁边,但如果你问的话......

【问题讨论】:

  • 说实话,我不太明白你的目标是什么。创建testvertices 的规则到底是什么?你的图中的顶点和边是什么?
  • 我刚刚编辑了testvertices,所以大一->大三,大三->大二,大二->大四。学生可以跳过几年(大一 -> 大四)但不能回去(大二 -> 大二)。我注意到 user1317221_G 的反应并没有引出这些年来隐含的方向(方向性)。这能回答你的问题吗,@GaborCsardi?
  • 好吧,不是真的,对不起。什么是顶点/边列表?图中的顶点和边是什么?顶点是大一、大三、大二、大四?就这四个?还是学生?边缘是什么?
  • 我正在尝试从一个类别映射到另一个类别,因此边和顶点都可以是大一、大三、大二和大四。我想要一棵树,显示从任何事物到高级的路径。如果有人从大二开始,然后变成大四,我希望​​ vertex=sophomore 和 edge=senior,如果有人经历了所有阶段,我需要在树中描绘所有阶段。 edit 所以,作为开始,我预计连续几年发生的所有变化都将变为 vertex=change_from 和 edge=change_to,连续几年没有变化将被忽略。
  • 我有点困惑。在图中,两个顶点通过边连接。所以如果你有人从大二转大四,那么大二和大四是通过有向边连接的吗?这就是你的意思?

标签: r dataframe igraph vertexdata


【解决方案1】:

如果我理解正确,你需要这样的东西:

elist <- lapply(seq_len(nrow(test)), function(i) {
  x <- as.character(test[i,])
  x <- unique(na.omit(x))
  x <- rep(x, each=2)
  x <- x[-1]
  x <- x[-length(x)]
  r <- matrix(x, ncol=2, byrow=TRUE)
  if (nrow(r) > 0) { r <- cbind(r, i) } else { r <- cbind(r, numeric()) }
  r
})

do.call(rbind, elist)

#                              i  
# [1,] "freshman"  "junior"    "1"
# [2,] "junior"    "senior"    "1"
# [3,] "freshman"  "junior"    "2"
# [4,] "junior"    "sophomore" "2"
# [5,] "sophomore" "senior"    "2"
# [6,] "freshman"  "junior"    "3"
# [7,] "junior"    "sophomore" "3"
# [8,] "sophomore" "senior"    "3"
# [9,] "sophomore" "senior"    "4"
#[10,] "sophomore" "senior"    "5"

这不是最有效的解决方案,但我认为它相当具有指导意义。我们为输入矩阵的每一行分别创建边,因此lapply。要从一行创建边,我们首先删除 NA 和重复项,然后将每个顶点包含两次。最后,我们删除第一个和最后一个顶点。这样我们创建了一个边列表矩阵,我们只需要删除第一个和最后一个顶点并将其格式化为两列(实际上将其保留为向量会更有效,没关系)。

在添加额外的列时,我们必须小心检查我们的边列表矩阵是否有零行。

do.call 函数会将所有内容粘合在一起。结果是一个矩阵,如果您愿意,可以通过as.data.frame() 将其转换为数据框,然后您还可以将第三列转换为数字。如果您愿意,也可以更改列名。

【讨论】:

  • 谢谢。看起来我比以前想象的更迷茫。也许你可以帮助我this other post?它更直接地说明了我的问题。
  • 你为什么迷路了?我的代码为您提供了您所要求的结果。不是吗?
  • 哦,我明白了。所以这回答了您的问题,并创建了您认为需要的数据框,但事实证明这不是您需要的数据框。
  • 是的。它给了我一个比我正在寻找的答案更简单的答案,但更简单总比没有好。我感谢你到目前为止帮助我。 :-)
【解决方案2】:

这是你想要的好吗...

test1<-c(test[[2]],test[[3]],test[[4]])
test2<-c(test[[3]],test[[4]],test[[5]])
df<-data.frame(vertex=test1,edge=test2)
df1<-df[complete.cases(df),]
result<-df1[df1$vertex != df1$edge,]

【讨论】:

  • 您的代码忽略了更改的方向,即,它会导致 vertex=freshman 和 edge=junior,反之亦然。我希望改变的方向会被保留。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-14
相关资源
最近更新 更多