使用标识符转置数据

Transpose data using an identifier

我有一个文本文件 (blast software output),它只有一列和大约 40,000 行,如下所示。

基本上,我想使用 R 或终端将其转换为多列,第一列包含查询名称,其他列包含查询命中,每个命中都附加到新列

输入是这样的:

Query1
result1
result2
result3

Query2
result1
result2
result3
result4
result5   

Query3
result1
result2
result3
result4

预期输出

Query1 result1 result2 result3 
Query2 result1 result2 result3 result4 result5
Query3 result1 result2 result3 result4

它不是很优雅,但假设你的数据是一个名为 data 的向量,并且你有一些独特的东西可以分割(这里我使用 "q")你可以做这样的事情将它分割成列表项:

index <- c(grep("^q", data), length(data)+1)
reps <- c()
for (i in 1:(length(index)-1)) reps <- append(reps, rep(i, index[i+1]-index[i]))
split(data, reps)

或者,如果您的分隔符是查询结果块之间的 space,您可以使用 readLines 读取它并使用 grep("^$", data)

考虑 运行 readLines() 逐行读取文本文件,构建一个大的字符向量列表。下面还迭代地将 header 部分(即 Query1Query2)映射到各个字符向量的名称:

con <- file("/path/to/text/file.txt", open="r")

datalist <-  c()
while (length(line <- readLines(con, n=1, warn = FALSE)) > 0) {

  if (grepl("Query", line)==TRUE){
    query <- c()                                              # RESET VECTOR
    qName <- line                                             # CAPTURE QUERY NAME
  }
  else if (grepl("([A-Za-z])", line)==TRUE){
    query <- c(query, line)                                   # APPEND LINE TO VECTOR
  }
  else if (line == ""){
    datalist <- c(datalist, setNames(list(query), qName))     # APPEND NAMED VECTOR TO LIST
  }
}

datalist <- c(datalist, setNames(list(query), qName))         # REMAINING LAST SECTION
close(con)

datalist

# $Query1
# [1] "result1" "result2" "result3"

# $Query2
# [1] "result1" "result2" "result3" "result4" "result5"

# $Query3
# [1] "result1" "result2" "result3" "result4"

感谢你们的帮助和建议 readLine 函数(我不知道它存在)。上面的代码并没有真正生成我希望的输出,但是,我能够修改你们的代码写我自己的作品。我是 R 和一般编码的新手,所以它可能不是最复杂的代码,但它完成了工作。这是:

con<- file("blast5.txt", open = "r")
## Calculate rows and column needed
l<-0; w<-0; i<-0
while (length(line <- readLines(con, n=1, warn = FALSE)) > 0) {
if (grepl("Query", line)==TRUE){
l=l+1
if (i>w){
  w<-i
}
i<-0
  }
  else if (grepl(">", line)==TRUE){  # COUNT RESULTS UNDER EACH QUERY
i<-i+1
  }
}
# Make an empty array to store the data
blast<- array(NA,c(l,w+1))
close(con)
i<- 0; j<-1
con<- file("blast5.txt", open = "r")
while (length(line <- readLines(con, n=1, warn = FALSE)) > 0) {

  if (grepl("Query", line)==TRUE){
    i=i+1
    j<-1
    blast[i,1] <- line           #STORE QUERY NAME IN FIRST COLUMN
  }
  else if (grepl(">", line)==TRUE){
     j<-j+1
     blast[i,j]<- line           #STORE RESULTS IN SEPARATE COLUMNS 
  }
}
close(con)