【问题标题】:How to ignore a missing sheet in a rbind function?如何忽略 rbind 函数中缺少的工作表?
【发布时间】:2021-12-21 14:20:16
【问题描述】:

我需要帮助解决这个我不断遇到的错误。

我正在尝试构建包含各种工作表的 4 个 excel 文件的组合 data.frame。

但是,由于缺少 excel 'Mal' excel 文件中名为“j”的工作表,代码将无法运行并不断返回

错误:未找到工作表“j”

请问我该如何解决这个错误?

谢谢。

import_partnersubmissions_ALT <- function(){
  filelist <- list.files(path = "./Partner Submissions/", pattern = "*.xlsx")
  print(filelist)
  master <- data.frame()
  for(x in filelist){
    if(str_detect(x,"Bru")){
      print("Reading Bru...")
      master <- rbind(master,
                      read_partnerALT(x, "a"),
                      read_partnerALT(x, "b"),
                      read_partnerALT(x, "c"),
                      read_partnerALT(x, "d"),
                      read_partnerALT(x, "e"),
                      read_partnerALT(x, "f"),
                      read_partnerALT(x, "g")
      )
    }else if(str_detect(x,"Mal")){
      print("Reading Mal...")
      master <- rbind(master,
                      read_partnerALT(x, "h"),
                      read_partnerALT(x, "i"),
                      read_partnerALT(x, "j"),
                      read_partnerALT(x, "k")
      )
    }else if(str_detect(x,"Sgp")){
      print("Reading Sgp...")
      master <- rbind(master,
                      read_partnerALT(x, "l"),
                      read_partnerALT(x, "m"),
                      read_partnerALT(x, "n"),
                      read_partnerALT(x, "o")
      )
    }else if(str_detect(x,"Mld")){
      print("Reading Mld...")
      master <- rbind(master,
                      read_partnerALT(x, "p"),
                      read_partnerALT(x, "q"),
                      read_partnerALT(x, "r"),
                      read_partnerALT(x, "s")
      )
    }
  }

【问题讨论】:

  • 您可以尝试将read_partnerALT 函数包装成try 函数。
  • 请您进一步解释一下吗?
  • 如果你使用try(read_partnerALT(x, "j")) 它仍然会抛出一个错误,但你的脚本不会中断。或者,只需删除 read_partnerALT(x, "j")
  • 是的,当我删除该行时,它会抛出另一个错误:“匹配错误。名称(clabs,名称(xi)):名称与以前的名称不匹配”

标签: r if-statement data.table rbind openxlsx


【解决方案1】:

(在前面,你用 标记了这个,所以我假设你使用的是data.table 包。如果不是,那么下面的大部分内容仍然适用,尽管你需要使用do.call(rbind, list(...)) 代替rbindlist(list(...))。)

rbind 可以使用 NULL 参数,所以使用 tryCatch 进行包装。不过每次写都比较麻烦,建议用rbindlist

master <- rbindlist(
  c(list(master), 
    lapply(c("h", "i", "j", "k"),
           function(S) tryCatch(read_partnerALT(x, S), error = function(e) NULL)))
)

我不知道read_partnerALT的定义,所以可以稍微简化一下,但前提是:

  • 遍历您的工作表名称c("h", "i", ...)
  • 将其传递给真正调用read_partnerALT 但包装在tryCatch(.) 中的匿名函数;
  • 如果读取该工作表时出现任何类型的错误,它将改为为该工作表返回 NULL 并静默继续

我并不总是喜欢默默地做这样的事情,所以为了简洁,我们可以让它更值得注意:

func <- function(S) {
  tryCatch(
    read_partnerALT(x, S),
    error = function(e) {
      warning(conditionMessage(e))
      NULL
    })
}
master <- rbindlist( c(list(master), lapply(c("h", "i", "j", "k"), func)) )

演示:

library(data.table)
MT <- as.data.table(mtcars)

演示错误情况:

rbindlist(lapply(c("cyl", "gear", "quux"), function(S) MT[get(S) == 4,]))
# Error in .checkTypos(e, names_x) : 
#   Object 'quux' not found amongst mpg, cyl, disp, hp, drat and 6 more

静默修复:

rbindlist(lapply(c("cyl", "gear", "quux"), function(S) tryCatch(MT[get(S) == 4,], error = function(e) NULL)))
#       mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear
#     <num> <num> <num> <num> <num> <num> <num> <num> <num> <num>
#  1:  22.8     4 108.0    93  3.85 2.320 18.61     1     1     4
#  2:  24.4     4 146.7    62  3.69 3.190 20.00     1     0     4
#  3:  22.8     4 140.8    95  3.92 3.150 22.90     1     0     4
# ...

警告修复:

rbindlist(lapply(c("cyl", "gear", "quux"), function(S) tryCatch(MT[get(S) == 4,], error = function(e) {warning(conditionMessage(e)); NULL;})))
# Warning in value[[3L]](cond) :
#   Object 'quux' not found amongst mpg, cyl, disp, hp, drat and 6 more
#       mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear
#     <num> <num> <num> <num> <num> <num> <num> <num> <num> <num>
#  1:  22.8     4 108.0    93  3.85 2.320 18.61     1     1     4
#  2:  24.4     4 146.7    62  3.69 3.190 20.00     1     0     4
#  3:  22.8     4 140.8    95  3.92 3.150 22.90     1     0     4
# ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-18
    • 2012-10-26
    • 2014-12-24
    • 2012-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-19
    相关资源
    最近更新 更多