结合循环和lapply

时间:2014-06-15 13:23:07

标签: r for-loop lapply sapply

我对R很新,并且发现它非常强大。我正在尝试创建一个具有多个级别的数据框。我有3组(主题)称为" group1"," group2"和" group3"谁有每19个测试(名字无关紧要)。在这19个测试的每个测试中,我感兴趣的是7个组件中有3个组件,分别叫做b1,b2和b3。

到目前为止我尝试过:对于每个患者,19个测试形成19列,7行(组件)因此,我感兴趣的组件是19个测试中的每个测试的5,6,7:

sapply(x, '[', XXX, j)

我的最终代码是:

for (j in 1:19) {
   x = lapply(c('group1', 'group2', 'group3'), function(i) {
      filenames = dir(file.path('c:/19/7', i),
                 pattern = 'sRL.txt', full.names = T)
      x = lapply(filenames, read.table, sep = '')
      bb1 = sapply(x, '[', 5, j)
      bb2 = sapply(x, '[', 6, j)
      gg = sapply(x, '[', 7, j)
      pcode = as.numeric(gsub('_.*', '', basename(filenames)))
      data.frame(group = i, tests= j, pcode, b1= bb1, b2= bb2, g = gg)
   })
}

请问您能否建议如何创建一个漂亮的数据框,将每个组的每个主题的19个测试中的组件5,6,7组合在一起?

1 个答案:

答案 0 :(得分:0)

提供样本数据会更好,但在您的情况下,我可以看到它是如何困难的,因为文件的组织是您尝试处理的问题。

如果我理解正确,每位患者都有自己的所有测试文件。每个文件有19列(每个测试一列)和7行(每个测试组件一行)。文件(患者)被组织成组,其中每个组位于不同的目录中。

作为输出,您需要每个文件的行5:7,转换为每个组件有一列,每个测试每行1行。

我认为这样可以合理地完成你想做的事情,虽然没有完整的数据集就无法测试......

## not tested...
get.group <- function(g) {
  get.file <- function(x,g) {
    df <- read.table(x,sep="")
    data.frame(group=g, test=1:ncol(x), 
               pcode=gsub('_.*', '', basename(x)), t(x[5:7,]))
  }
  filenames <- dir(file.path('c:/19/7', g), pattern = 'sRL.txt', full.names = T)
  result    <- do.call(rbind,lapply(filenames,get.file,g))
}
final <- do.call(rbind,lapply(paste0("group",1:3),get.group))
colnames(final)[4:6] <- c("bb1","bb2","g")

因此,从外部开始工作:对于每个组,调用函数get.group(...),结果按行方式绑定在一起。 get.group(...)反过来抓取该组的文件名,并为每个文件名调用get.file(...),将结果按行绑定。最后,get.file(...)读取文件并创建一个数据框,其中包含组名,患者代码,测试编号以及所有19个测试的三个组成部分的结果。