【问题标题】:R: using foreach to read csv data and apply functions over the data and export back to csvR:使用 foreach 读取 csv 数据并对数据应用函数并导出回 csv
【发布时间】:2020-04-13 23:53:55
【问题描述】:

我有 3 个 csv 文件,分别是 file1.csvfile2.csvfile3.csv

现在对于文件的每个,我想导入 csv 并对它们执行一些功能,然后导出转换后的 csv。因此,输入 3 个 csv,输出 3 个转换后的 csv。而且只有 3 个独立的任务。所以我想我可以尝试使用foreach%dopar%。请不要说我使用的是 Window 机器。

但是,我无法让它工作。

library(foreach)
library(doParallel)
library(xts)
library(zoo)
numCores <- detectCores()
cl <- parallel::makeCluster(numCores)
doParallel::registerDoParallel(cl)

filenames <- c("file1.csv","file2.csv","file3.csv")
foreach(i = 1:3, .packages = c("xts","zoo")) %dopar%{
  df_xts          <- data_processing_IMPORT(filenames[i])
  ddates                <- unique(date(df_xts))
}

如果我注释掉最后一行ddates &lt;- unique(date(df_xts)),代码运行良好,没有错误。

但是,如果我包含最后一行代码,我会收到以下错误,我不知道如何解决。我尝试添加.export = c("df_xts")

Error in { : task 1 failed - "unused argument (df_xts)"

还是不行。我想了解我的逻辑有什么问题,我应该如何解决这个问题?我只是想对数据应用简单的函数,我还没有转换数据并将它们单独导出到 csv。然而我已经被困住了。

有趣的是我写了下面的简单代码,它工作正常。在foreach中,a就像上面的df_xts一样,被存储在一个变量中,并传递给Fun2进行处理。下面的代码工作正常。但上面没有。我不明白为什么。

numCores <- detectCores()
cl <- parallel::makeCluster(numCores)
doParallel::registerDoParallel(cl)


# Define the function
Fun1=function(x){
  a=2*x
  b=3*x
  c=a+b
  return(c)
}

Fun2=function(x){
  a=2*x
  b=3*x
  c=a+b
  return(c)
}

foreach(i = 1:10)%dopar%{
  x <- rnorm(5)
  a <- Fun1(x)
  tst <- Fun2(a)
  return(tst)
  }
### Output: No error

parallel::stopCluster(cl)

更新:我发现问题在于那里的 date 函数可以提取 csv 文件中的日期数,但我不知道如何解决这个问题。

【问题讨论】:

  • 函数data_processing_IMPORT有什么作用?我在你给定的包中找不到它
  • 它所做的只是 read.csv 并将其转换为 xts 对象。就是这样。
  • 你使用date()错了,你想使用as.Date()date() 返回您当前的系统时间。

标签: r foreach parallel-foreach


【解决方案1】:

foreach() 的使用是正确的。您在ddates &lt;- unique(date(df_xts)) 中使用date(),但是这个function 以POSIX 形式返回当前系统时间并且不需要任何参数。因此,参数错误与date() 函数有关。

所以我猜你想改用as.Date() 或类似的东西。

ddates <- unique(as.Date(df_xts))

【讨论】:

    【解决方案2】:

    我在读取、修改和写入多个 CSV 文件时遇到了同样的问题。我试图为此找到一个tidyverse 解决方案,虽然它并不能真正解决上面的date 问题,但这里是--如何使用map 读取、修改和写入几个csv 文件。 987654324@。

    library(tidyverse)
    
    
    # There are some sample csv file in the "sample" dir.
    # First get the paths of those.
    
    datapath <- fs::dir_ls("./sample", regexp = ("csv"))
    
    datapath
    
    # Then read in the data, such as it is a list of data frames
    # It seems simpler to write them back to disk as separate files.
    # Another way to read them would be:
    # newsampledata <- vroom::vroom(datapath, ";", id = "path")
    # but this will return a DF and separating it to different files
    # may be more complicated.
    
    sampledata <- map(datapath, ~ read_delim(.x, ";"))
    
    # Do some transformation of the data.
    # Here I just alter the column names.
    
    transformeddata <- sampledata %>% 
      map(rename_all, tolower)
    
    # Then prepare to write new files
    names(transformeddata) <- paste0("new-", basename(names(transformeddata)))
    
    # Write the csv files and check if they are there
    map2(transformeddata, names(transformeddata), ~ write.csv(.x, file = .y))
    dir(pattern = "new-")
    

    【讨论】:

      猜你喜欢
      • 2019-06-15
      • 1970-01-01
      • 2018-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多