我使用循环来导入一些名为"文件_ij.xlsx"的Excel文件并将其绑定在一起,其中i可以是1到4,j可以是1到3.但是i=3或j=2不存在,所以我总共有6个文件.这就是为什么我使用tryCatch跳过丢失的文件并显示错误消息的原因.下面的代码实现了我想要的功能.但除了导入之外,我还想创建一个数据帧来记录i和j的错配组合.但这并不像我预期的那样工作.有人能告诉我为什么吗?代码如下:

library(readxl)
library(tidyverse)

df <- data.frame() # empty DF for storing imported data
missing_df <- data.frame(i = numeric(), j = numeric()) # empty DF for storing information about missing records

for (i in 1:4){
  
  for (j in 1:3) {
    
    tryCatch({
      
      out <- read_xlsx(paste0("C:\\test\\File_", i, j, ".xlsx"))
      df <- bind_rows(df, out)
      
    },
    
    error = function(e) {
      
      message(paste0("The following do not exist: i = ", i, ", j = ", j)) # this works fine, message is displayed
      missing_df <- bind_rows(missing_df, data.frame(i = i, j = j)) # This doesn't work as expected, rows are not appended to the DF
      
    }
    )
    
  }
}

推荐答案

一般作用域

这与作用域有关.在抛出错误的情况下,调用错误处理程序function,如果它们与全局环境中的变量具有相同的名称,则调用错误处理程序function,其跟踪其自身的变量even.下面的例子说明了这一 idea :

a <- 1
f <- function() {
  cat("Before a is defined in the function it takes the value from global:", a, "\n")
  a <- 2
  cat("After a is defined in the function it takes the value from local:", a, "\n")
}
f()
# Before a is defined in the function it takes the value from global: 1 
# After a is defined in the function it takes the value from local: 2 
cat("After the function is called we only see the global scope:", a, "\n")
# After the function is called we only see the global scope: 1

您可以在全局环境中使用<<-为函数赋值,但通常最好避免这种模式:

a <- 1
g <- function() {
  a <<- 2
}
print(a)
# [1] 1
g() ## changes a on global scope
print(a)
# [1] 2

try 捕捉

try 捕捉以内,同样的 idea 也适用.主代码在global范围内求值(也就是说,我们可以在global范围内修改变量,而不需要<<-),但在错误处理程序(实际上是function)中,我们需要使用<<-对全局sope进行赋值:

even <- list()
even2 <- list()
odd <- list()
odd_bad <- list()

for (i in 1:2) {
  for (j in 1:3) {
    try 捕捉({
      stopifnot("i * j must be even" = i * j %% 2 == 0)
      ## works because this code is evaluated on global scope
      even2 <- c(even2, list(c(i, j))) 
      even <<- c(even, list(c(i, j)))
    }, error = function(err) {
      ## does not work creates a local version of odd_bad which is later discarded
      odd_bad <- c(odd_bad, list(c(i, j)))
      odd <<- c(odd, list(c(i, j)))
    })
  }
}

length(even)
# [1] 2
length(even2)
# [1] 2
length(odd)
# [1] 4
length(odd_bad)
# [1] 0

避免全局赋值的更好模式

因为在全局范围内通过<<-赋值变量应该谨慎使用,所以更好的解决方案是从主代码和错误处理程序中返回一个元素,并使用一个标志(例如类)进行修改,然后我们可以使用它轻松地过滤好的和坏的结果.这完全避免了全局赋值:

res <- list()

for (i in 1:2) {
  for (j in 1:3) {
    res <- c(res, 
      try 捕捉({
        stopifnot("i * j must be even" = i * j %% 2 == 0)
        list(structure(list(c(i, j)), class = "good"))
      }, error = function(err) {
        list(structure(list(c(i, j)), class = "bad"))
      })
     )
  }
}

Filter(\(e) inherits(e, "good"), res) ## all good results
Filter(\(e) inherits(e, "bad"), res)  ## all badd results

R相关问答推荐

使用sensemakr和fixest feols模型(R)

是否可以 Select 安装不带文档的R包以更有效地存储?

使用ggplot将平滑线添加到条形图

检测(并替换)字符串中的数学符号

如何根据条件计算时差(天)

如何使用R对每组变量进行随机化?

使用ggsankey调整Sankey图中单个 node 上的标签

移除仪表板Quarto中顶盖和车身之间的白色区域

根据现有列的名称和字符串的存在进行变异以创建多个新列

比较理论阿尔法和经验阿尔法

如何识别倒排的行并在R中删除它们?

Ggplot2中geom_tile的动态zoom

基于Key->Value数据帧的基因子集相关性提取

如何使用前缀作为匹配来连接数据帧?

名字的模糊匹配

在ggplot2图表中通过端点连接点

R没有按顺序显示我的有序系数?

如何在访问之前下载的输入时同时上传和处理所有指定的shiny 输入?

如何在不使用SHINY的情况下将下拉滤镜列表添加到ggploy?

如何修复geom_rect中的层错误?