R:使用 foreach 读取 csv 数据并对数据应用函数并导出回 csv
R: using foreach to read csv data and apply functions over the data and export back to csv
我有 3 个 csv 文件,即 file1.csv
、file2.csv
和 file3.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 <- 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 文件中的日期数,但我不确定如何解决这个问题。
foreach()
的用法是正确的。您在 ddates <- unique(date(df_xts))
中使用 date()
,但此 function returns 当前系统时间为 POSIX,不需要任何参数。因此,参数错误与 date()
函数有关。
所以我猜您想改用 as.Date()
或类似的东西。
ddates <- unique(as.Date(df_xts))
我 运行 遇到了关于读取、修改和写入多个 CSV 文件的相同问题。我试图为此找到一个 tidyverse
解决方案,虽然它并没有真正解决上面的 date
问题,但这里是 -- 如何读取、修改和写入几个 csv 文件使用 map
来自 purrr
。
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-")
我有 3 个 csv 文件,即 file1.csv
、file2.csv
和 file3.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 <- 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 文件中的日期数,但我不确定如何解决这个问题。
foreach()
的用法是正确的。您在 ddates <- unique(date(df_xts))
中使用 date()
,但此 function returns 当前系统时间为 POSIX,不需要任何参数。因此,参数错误与 date()
函数有关。
所以我猜您想改用 as.Date()
或类似的东西。
ddates <- unique(as.Date(df_xts))
我 运行 遇到了关于读取、修改和写入多个 CSV 文件的相同问题。我试图为此找到一个 tidyverse
解决方案,虽然它并没有真正解决上面的 date
问题,但这里是 -- 如何读取、修改和写入几个 csv 文件使用 map
来自 purrr
。
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-")