【问题标题】:Inexplicable error in a for inside a for in RR中的for内部出现莫名其妙的错误
【发布时间】:2021-11-30 01:51:33
【问题描述】:

我只是在 for 中做一个 for 以使用以下代码从不同的 csv 文档读取到 R 中的元素列表中,我是从两个不同的变量中获取的,频率类型 freq <- c('4', '8', '13', '38','N_4','N_8','N_13','N_38') 和值的类型 @ 987654328@。这两个字符串变量用于在相应的 csv 中命名,如在图像中看到的工作目录中所示。

我正在使用以下代码从同一目录中读取。

#Prepare data options
freq <- c('4', '8', '13', '38','N_4','N_8','N_13','N_38')
typ <- c('PE','QS')


dataintra <- list()

for (j in 1:2){
  for (k in 1:8){
    
    dataintra[[j*k]] <- read.csv(sprintf('M1_PredErr_Results_%s_%s.csv', typ[j], freq[k]), sep=',', header=TRUE)
    
  }
}

问题是,虽然我期待一个完整列表的列表,但我发现不同的列表编号为 NULL,如下面的屏幕截图所示。

试图理解迭代背后的逻辑,for-for 以一种奇怪的方式跳跃,奇数与偶数相比,这使得从 9 到 15 的赔率无法完成。我正在附加列表中每个元素的迭代顺序。

我想了解为什么 for-for 中的 R 具有这种不稳定的行为,以及这样做的正确方法是什么。我可以考虑其他效率较低的方法来做到这一点,例如制作一个索引向量,并附有iteration &lt;- c('PE_4', 'PE_8', 'PE_13', 'PE_38','PE_N_4','PE_N_8','PE_N_13','PE_N_38','QS_4', 'QS_8', 'QS_13', 'QS_38','QS_N_4','QS_N_8','QS_N_13','QS_N_38') 的两个特征,这很成功,但如果有人能提供帮助,我真的很想了解其中的逻辑。

提前致谢!

【问题讨论】:

  • 你知道j*k是什么意思吗?
  • 您在逻辑中看到多个错误的影响: 1. dataintra 中的哪个元素分配给 j = 2 和 k = 1? which for j = 1 and k = 2. 2. 你认为你会如何曾经在你的 for-for 循环中得到索引 9?

标签: r list for-loop


【解决方案1】:
#Prepare data options
freq <- c('4', '8', '13', '38','N_4','N_8','N_13','N_38')
typ <- c('PE','QS')

我建议使用命名列表(我们可以使用文件名作为标识)

dataintra <- list()

for (this_freq in freq){
  for (this_typ in typ){
    this_name <- sprintf('M1_PredErr_Results_%s_%s.csv', this_typ, this_freq)
    dataintra[[this_name]] <- read.csv(this_name, sep=',', header=TRUE)
  }
}

或者,如果您更喜欢数字索引:

index <- 1
for (this_freq in freq){
  for (this_typ in typ){
    this_name <- sprintf('M1_PredErr_Results_%s_%s.csv', this_typ, this_freq)
    dataintra[[index]] <- read.csv(this_name, sep=',', header=TRUE)
    index <- index + 1
  }
}

【讨论】:

    【解决方案2】:

    您的问题在于 List 元素的索引: dataintra[[j*k]]

    例如 9 只能由 3x3 组成,因此列表的索引 9 永远不会被填充。因为你只乘 (1:2)x(1:8)

    您还可以覆盖多个索引,例如索引 8 是 (1,8) 和 (4,2)。

    我认为使用 R 已经提供的一些功能会更容易,而不是使用 for 循环:

    #Prepare data options
    freq <- c('4', '8', '13', '38','N_4','N_8','N_13','N_38')
    typ <- c('PE','QS')
    
    
    
    # get all combinations of typ and freq
    input<- expand.grid(typ,freq)
    
    ## get a List of all the adresses
    # mapply iterates over two vectors (Var1 and Var2 of the input dataframe)
    # and performs a function on them
    csv_adresses <- mapply(function(x,y){sprintf('M1_PredErr_Results_%s_%s.csv',x,y)},
                           input$Var1,input$Var2)
    
    # read all the csv files of the adresses
    dataintra <- sapply(csv_adresses,read.csv,header=TRUE)
    

    【讨论】:

    • 谢谢你,也是一个清晰有效的答案,我只是没看到。
    • 顺便说一句@Sandwichnick,我尝试了这个选项,因为它更清晰,看起来更优化,我在执行时发现了一个问题,而我可以看到字符串向量csv_adresses该函数没有通过@987654324 @。知道为什么吗?
    • @UnaiVicente 只是一个想法/评论:您认为优化您的特定任务更重要的是什么:减少几毫秒或易读性?虽然在很多情况下我更喜欢apply- 系列解决方案,但对于这里的问题,我总是更喜欢 for 循环。它看起来更清晰,更容易看到发生在我身上的事情......但这只是我的意见;)
    • 对不起,那是我的。我混淆了 sapply 参数。我编辑了我的答案。正如@dario 已经提到的那样:如果您对 for 循环更满意,那么在这种情况下使用它们是完全有效的。我认为 sapply 不会运行得那么快。
    • 我在谈论优化,因为我读到 apply 系列函数比 r 中的 for 循环要少得多,这是我评论的唯一基础。此外,代码行数更少。
    猜你喜欢
    • 2012-03-12
    • 1970-01-01
    • 1970-01-01
    • 2019-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多