{ 中的 FOREACH 循环错误:任务 1 失败 - "could not find function "dbGetQuery""
FOREACH LOOP Error in { : task 1 failed - "could not find function "dbGetQuery""
我在 R 中的简单实现方面经验丰富,但是我不熟悉通过 R 与 SQL 通信以及并行编程(在今天之前没有这两件事的经验)。我根据博客、论坛等的提示编写了以下代码。
library(doParallel)
library(RMySQL)
library(DBI)
library(foreach)
cl <- makeCluster(12)
registerDoParallel(cl)
Postcodecsv <- read.csv("C:/Users/Henry Crosby/Desktop/PostcodeLatLong.csv")
mydb = dbConnect(MySQL(), user='****', password="******* ****",
dbname='population_distance', host='****.**.*.*')
dbListFields(mydb,'Postcodes')
foreach (a = 1:120000, .combine="rbind") %dopar% {
Done <- dbGetQuery(mydb, paste("select FID, Postcode2, (6371 * acos( cos(
radians( ",Postcodecsv[a,6],"))*cos(radians(latitude))*cos(radians(Longitude)-radians(",Postcodecsv[a,5],"))+sin(radians(",Postcodecsv[a,6],") )* sin( radians( latitude ) ) ) ) AS distance from Postcodes having distance < 2 ORDER BY distance",sep=" "))
write.table(Done,file="C:/Users/Henry Crosby/Desktop/2km.csv",append=TRUE, col.names=FALSE, sep=",")
}
此计算在 for 循环中进行但需要很长时间(我必须将其应用于大型数据集!)。当我 运行 以上代码时,出现以下错误!谁能告诉我为什么会出现错误以及我该如何解决它!
Error in { : task 1 failed - "could not find function "dbGetQuery""
问题是 foreach 是 auto-exporting mydb
对象,但它无法正常工作,因为包含套接字连接的对象无法在进程之间序列化和复制。
我建议您使用 clusterEvalQ
函数初始化集群 worker,以便在每个 worker 上创建 mydb
。你可以尝试这样的事情:
clusterEvalQ(cl, {
library(RMySQL)
mydb <- dbConnect(MySQL(), user='****', password="******* ****",
dbname='population_distance', host='****.**.*.*')
NULL
})
但是,您仍然需要使用 foreach .noexport="mydb"
选项来阻止 foreach auto-exporting mydb
。您还可以使用 foreach .verbose=TRUE
选项来验证哪些对象正在 auto-exported 工作人员。
为什么要使用 R 处理 sql 到 csv 的迁移?考虑一个完整的 SQL 解决方案并将处理留在数据库引擎上。具体就是加入Postcodestable和PostcodeLatLong csv数据(当然是导入到MySQL数据库)。然后使用 MySQL 的 OUTFILE 工具。总而言之,您只需 运行 dbGetQuery()
一次,无需并行循环:
expotCSV <- dbGetQuery("SELECT FID, Postcode2, (6371 * acos( cos(
radians(Postcodecsv.col6))*cos(radians(latitude))*cos(radians(Longitude)-
radians(Postcodecsv.col5))+sin(radians(Postcodecsv.col6))* sin(radians(latitude))))
AS distance
FROM Postcodes
INNER JOIN PostcodeLatLong ON csv.joinfield = PostcodeLatLong.joinfield
HAVING distance < 2
ORDER BY distance
INTO OUTFILE 'C:/Users/Henry Crosby/Desktop/2km.csv'
FIELDS ENCLOSED BY '\"'
TERMINATED BY ';'
ESCAPED BY '\"'
LINES TERMINATED BY '\r\n';")
挑战在于找到 joinfield
或两个 table 之间的关系。但是,SQL 还允许 cartesian product or the cross join(对于看似无关的 tables),其中查询 returns 列出的 tables 之间的总组合集。您可以通过某些过滤子句使用 where 子句:
FROM Postcodes, PostcodeLatLong
WHERE Postcodes.somefactor = "..." AND PostcodeLatLong.somefactor = "..."
或者,MySQL 的 CROSS JOIN
(没有 ON 子句的 JOIN)
FROM Postcodes CROSS JOIN PostcodeLatLong
WHERE Postcodes.somefactor = "..." AND PostcodeLatLong.somefactor = "..."
我在 R 中的简单实现方面经验丰富,但是我不熟悉通过 R 与 SQL 通信以及并行编程(在今天之前没有这两件事的经验)。我根据博客、论坛等的提示编写了以下代码。
library(doParallel)
library(RMySQL)
library(DBI)
library(foreach)
cl <- makeCluster(12)
registerDoParallel(cl)
Postcodecsv <- read.csv("C:/Users/Henry Crosby/Desktop/PostcodeLatLong.csv")
mydb = dbConnect(MySQL(), user='****', password="******* ****",
dbname='population_distance', host='****.**.*.*')
dbListFields(mydb,'Postcodes')
foreach (a = 1:120000, .combine="rbind") %dopar% {
Done <- dbGetQuery(mydb, paste("select FID, Postcode2, (6371 * acos( cos(
radians( ",Postcodecsv[a,6],"))*cos(radians(latitude))*cos(radians(Longitude)-radians(",Postcodecsv[a,5],"))+sin(radians(",Postcodecsv[a,6],") )* sin( radians( latitude ) ) ) ) AS distance from Postcodes having distance < 2 ORDER BY distance",sep=" "))
write.table(Done,file="C:/Users/Henry Crosby/Desktop/2km.csv",append=TRUE, col.names=FALSE, sep=",")
}
此计算在 for 循环中进行但需要很长时间(我必须将其应用于大型数据集!)。当我 运行 以上代码时,出现以下错误!谁能告诉我为什么会出现错误以及我该如何解决它!
Error in { : task 1 failed - "could not find function "dbGetQuery""
问题是 foreach 是 auto-exporting mydb
对象,但它无法正常工作,因为包含套接字连接的对象无法在进程之间序列化和复制。
我建议您使用 clusterEvalQ
函数初始化集群 worker,以便在每个 worker 上创建 mydb
。你可以尝试这样的事情:
clusterEvalQ(cl, {
library(RMySQL)
mydb <- dbConnect(MySQL(), user='****', password="******* ****",
dbname='population_distance', host='****.**.*.*')
NULL
})
但是,您仍然需要使用 foreach .noexport="mydb"
选项来阻止 foreach auto-exporting mydb
。您还可以使用 foreach .verbose=TRUE
选项来验证哪些对象正在 auto-exported 工作人员。
为什么要使用 R 处理 sql 到 csv 的迁移?考虑一个完整的 SQL 解决方案并将处理留在数据库引擎上。具体就是加入Postcodestable和PostcodeLatLong csv数据(当然是导入到MySQL数据库)。然后使用 MySQL 的 OUTFILE 工具。总而言之,您只需 运行 dbGetQuery()
一次,无需并行循环:
expotCSV <- dbGetQuery("SELECT FID, Postcode2, (6371 * acos( cos(
radians(Postcodecsv.col6))*cos(radians(latitude))*cos(radians(Longitude)-
radians(Postcodecsv.col5))+sin(radians(Postcodecsv.col6))* sin(radians(latitude))))
AS distance
FROM Postcodes
INNER JOIN PostcodeLatLong ON csv.joinfield = PostcodeLatLong.joinfield
HAVING distance < 2
ORDER BY distance
INTO OUTFILE 'C:/Users/Henry Crosby/Desktop/2km.csv'
FIELDS ENCLOSED BY '\"'
TERMINATED BY ';'
ESCAPED BY '\"'
LINES TERMINATED BY '\r\n';")
挑战在于找到 joinfield
或两个 table 之间的关系。但是,SQL 还允许 cartesian product or the cross join(对于看似无关的 tables),其中查询 returns 列出的 tables 之间的总组合集。您可以通过某些过滤子句使用 where 子句:
FROM Postcodes, PostcodeLatLong
WHERE Postcodes.somefactor = "..." AND PostcodeLatLong.somefactor = "..."
或者,MySQL 的 CROSS JOIN
(没有 ON 子句的 JOIN)
FROM Postcodes CROSS JOIN PostcodeLatLong
WHERE Postcodes.somefactor = "..." AND PostcodeLatLong.somefactor = "..."