簡體   English   中英

R:如何將文本文件遞歸到列表列表中?

[英]R: How to read text file into a lists of lists recursively?

我有一個文本文件,格式為:

date=1638.1.16
player=\"BYZ\"
savegame_version={
\tfirst=1
\tsecond=25
\tthird=1
\tforth=0
\tname=\"England\"
}
mod_enabled={
\t\"Large Font\"
\t\"Large Tooltips\"
}

我想做的是將其讀入R作為字符向量列表,其中{和}符號表示創建另一個列表。 結果應如下所示:

[[1]]
[1] "date=1638.1.16"

[[2]]
[1] "player=\"BYZ\""

[[3]]
[[3]][[1]]
[1] "savegame_version={"

[[3]][[2]]
[1] "\tfirst=1"

[[3]][[3]]
[1] "\tsecond=25"

[[3]][[4]]
[1] "\tthird=1"

[[3]][[5]]
[1] "\tforth=0"

[[3]][[6]]
[1] "\tname=\"England\""

[[3]][[7]]
[1] "}"

[[4]]
[[4]][[1]]
[1] "mod_enabled={"

[[4]][[2]]
[1] "\t\"Large Font\""

[[4]][[3]]
[1] "\t\"Large Tooltips\""

[[4]][[4]]
[1] "}"

我嘗試使用創建列表的函數遍歷數據行,其中{符號再次遞歸調用同一函數。 問題在於結果只是一個列表,而不是如上所示的嵌套列表。

當前函數寫為:

list_create <- function(vector){
  temp_list <- list()
  for(i in 1:length(vector)){
    if(str_detect(vector[i], pattern = "\\{")) {
      list_create(vector[i+1:length(vector)])
    }
    if(str_detect(vector[i], pattern = "\\}")) {
      return(temp_list)
    }
    temp_list <- append(temp_list, vector[i])
  }
}

有什么辦法可以得到我想要的結果嗎?

您有幾層子列表? 對於您提供的示例(只有兩個級別的列表),它應該可以工作:

# read the file in
txt <- readLines("listtext.txt")

# create an empty list
main.list <- list()

# indicator that we are within sublist
sub=FALSE

# loop through each line
for( i in seq(txt) ){

  # check if the string opens a new sublist
  if ( grepl("\\{", txt[i]) ){
    sub.list <- list()   # start a new sublist
    sub.list <- c(sub.list, txt[i])  # add the line as the first line in the new list
    sub = TRUE                       # inside the sublist

  # check if we need to close sublist
  } else if(grepl("\\}", txt[i]) ){
    sub.list <- c(sub.list, txt[i])  # add the last line to sublist
    main.list <- c(main.list, list(sub.list))   # add sublist to the main list
    sub=FALSE                        # no longer inside sublist

  # if we are within sublist    
  } else if(sub) {
    sub.list <- c(sub.list, txt[i])

  # regular record    
  } else {
    main.list <- c(main.list, txt[i] )
  }
}

main.list
# [[1]]
# [1] "date=1638.1.16"
# 
# [[2]]
# [1] "player=\\\"BYZ\\\""
# 
# [[3]]
# [[3]][[1]]
# [1] "savegame_version={"
# 
# [[3]][[2]]
# [1] "\\tfirst=1"
# 
# [[3]][[3]]
# [1] "\\tsecond=25"
# 
# [[3]][[4]]
# [1] "\\tthird=1"
# 
# [[3]][[5]]
# [1] "\\tforth=0"
# 
# [[3]][[6]]
# [1] "\\tname=\\\"England\\\""
# 
# [[3]][[7]]
# [1] "}"
# 
# 
# [[4]]
# [[4]][[1]]
# [1] "mod_enabled={"
# 
# [[4]][[2]]
# [1] "\\t\\\"Large Font\\\""
# 
# [[4]][[3]]
# [1] "\\t\\\"Large Tooltips\\\""
# 
# [[4]][[4]]
# [1] "}"

如果您有許多遞歸子列表,則可以編寫一個遞歸函數:

main.list <- list()
subfun <- function(istart, txt){

  sub.list <- list()
  sub.list <- c(sub.list, txt[istart])
  j = istart + 1
  while( !grepl("\\}", txt[j]) ){

    if ( grepl("\\{", txt[j]) ){
      x <- subfun(j, txt)
      sub.list <- c(sub.list, list(x$sub) )  # add sublist to the main list
      j=x$iend

      # regular record    
    } else {
      sub.list <- c(sub.list, txt[j] )
    }    
    j <- j+1
  }
  sub.list <- c(sub.list, txt[j])
  return(list(sub=sub.list, iend=j))
}

# loop through each line
i=1
while( i <= length(txt) ){

  # check if the string opens a new sublist
  if ( grepl("\\{", txt[i]) ){
    x <- subfun(i, txt)
    main.list <- c(main.list, list(x$sub) )  # add sublist to the main list
    i=x$iend

    # regular record    
  } else {
    main.list <- c(main.list, txt[i] )
  }
  i <- i+1
}

對於您的示例,它將產生與第一種方法相同的結果

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM