【问题标题】:How to construct a network by subsetting based on time period如何通过基于时间段的子集来构建网络
【发布时间】:2013-11-01 19:00:29
【问题描述】:

我对这里的一切都很陌生。我试图付出更多努力使我的代码可读。我正在编写为多个文件运行函数的代码。我有超过 100 个文件,每个文件都包含带有时间(会话)的边缘列表,如下所示:

Header: Time Sender Receiver

      1    1       2
      1    1       3
      2    2       1
      2    2       1
      3    1       2
      3    1       2

该函数的目的是根据“时间”从每个文件中提取子网络。由于有 3 个不同的时间段,每个文件将有 3 个子网络。以下是我写的代码:

SubsetNetwork <-function (file) {
  df = read.csv(file)
  uniq <-unique(unlist(df$Time))
  edgelist=list()
  g=list()
  for (i in 1:length(uniq)){
    g <- lapply(split(df, df$Time), function(x) {
      graph.edgelist(as.matrix(x[c("Sender","Receiver")]), directed = T)
    })
    edgelist[[i]]=get.edgelist(g[[i]])

    filename=paste(fname, i, ".csv")
    write.csv(edgelist[[i]], filename)
  }
}   

这段代码将运行上面的函数。

temp = list.files(pattern="*.csv") 
for (i in 1:length(temp)){      
  file <-temp[i]              
  SubsetNetwork (file)
}    
  • 输入文件=626234T.csv
  • 输出文件 = 626234T1.csv、626234T2.csv、626234T3.csv。

我不断收到错误消息 (Error in g[[i]] : subscript out of bounds)。如果我一个一个地运行代码,它似乎可以工作。但是,如果我输入多个文件,它会为多个文件生成输出并停止工作。我不知道是什么导致了问题。

【问题讨论】:

  • 请更加努力使代码可读(和可重现)。仅仅发布一个没有库调用非基本函数的屏幕抓取是不够的。您还应该发布来自dput(head(df)) 的输出。
  • 我不确定我是否理解你在做什么,但这有帮助吗:lapply(split(df, df$Time), function(x) graph.edgelist(as.matrix(x[c("Sender", "Receiver")]), directed = T))? (df 是最后的数据帧(时间发送者等))。输出是 3 个类似 IGRAPH D--- 3 2 -- 的元素的列表。
  • 很抱歉我的代码不可读。我不习惯写代码。我试着自学。 @alexis_laz 谢谢。我想你的代码会有很大帮助。

标签: r list matrix


【解决方案1】:

如果您的代码在一个文件上运行良好,则您收到的错误表明您的代码没有问题。如果唯一时间点的数量 g[[i]] is out of bounds。

我怀疑正在发生的事情是存在格式错误或损坏的文件,该文件缺少 temp &lt;- list.files(*.csv) 获取的“时间”标头。

由于你不习惯写代码,我会为你经历、批评和修复一些东西:

SubsetNetwork <-function (file) {
  df = read.csv(file)
  uniq <-unique(unlist(df$Time))

data.frames 的列只是向量,所以这里不需要unlist。而是:

  uniq <-unique(df$Time)

足够了。

  edgelist=list()
  g=list()
  for (i in 1:length(uniq)){
    g <- lapply(split(df, df$Time), function(x) {
      graph.edgelist(as.matrix(x[c("Sender","Receiver")]), directed = T)
    })
    edgelist[[i]]=get.edgelist(g[[i]])

    filename=paste(fname, i, ".csv")
    write.csv(edgelist[[i]], filename)
  }
}

您实际上可能不需要for 循环。 lapplysplit 数据框将返回整个列表,因此可以移出循环。如果get.edgelist 被矢量化,这也可以移到循环之外。因为我实际上并不知道,所以我认为这不仅仅是为了安全:

  g <- lapply(split(df, df$Time), function(x) {
    graph.edgelist(as.matrix(x[c("Sender","Receiver")]), directed = T)
  })
  edgelist <- lapply(g, get.edgelist)

  for (i in 1:length(uniq)){
    filename=paste(fname, i, ".csv")
    write.csv(edgelist[[i]], filename)
  }
}

现在,您也不需要uniq,因为unique 时间点的数量只是g 和您的edgelist 的长度。

filename=paste(fname, i, ".csv") 时,paste 函数将在每个参数之间插入空格(即fname 1 .csv 而不是fname1.csv。您可以指定sep="" 来更改paste 的行为或使用paste0作为简写。

将所有内容重新组合在一起:

SubsetNetwork <-function (file) {
  df = read.csv(file)
  g <- lapply(split(df, df$Time), function(x) {
    graph.edgelist(as.matrix(x[c("Sender","Receiver")]), directed = T)
  })
  edgelist <- lapply(g, get.edgelist)

  for (i in 1:length(g)){
    filename=paste0(fname, i, ".csv")
    write.csv(edgelist[[i]], filename)
  }
}

【讨论】:

  • 非常感谢您的 cmets。因为我尝试自己学习 R,所以我使用了其他人的代码片段(即使我不确定他们真正做了什么)。不管怎样,多亏了你,我学到了很多。
  • 不客气!我注意到对于刚学习的人来说有很多先进的概念,所以我想我会帮忙:)
猜你喜欢
  • 1970-01-01
  • 2019-09-22
  • 2011-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-23
  • 1970-01-01
相关资源
最近更新 更多