2

我在 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 循环中工作,但需要永远(我必须将其应用于 LARGE 数据集!)。当我运行上面的代码时,我得到下面的错误!有人可以告诉我为什么会出现错误以及如何解决它!

{ 中的错误:任务 1 失败 - “找不到函数“dbGetQuery””

4

2 回答 2

1

问题是 foreach 正在自动导出mydb对象,但它不能正常工作,因为包含套接字连接的对象无法在进程之间进行序列化和复制。

我建议您使用在每个工作人员clusterEvalQ上创建的函数来初始化集群工作mydb人员。您可以尝试以下方法:

clusterEvalQ(cl, {
  library(RMySQL)
  mydb <- dbConnect(MySQL(), user='****', password="******* ****",
                    dbname='population_distance', host='****.**.*.*')
  NULL
})

mydb但是,您仍然需要使用 foreach.noexport="mydb"选项来防止 foreach 自动导出。您还可以使用 foreach.verbose=TRUE选项来验证哪些对象正在自动导出到工作人员。

于 2016-01-07T22:21:49.593 回答
0

为什么使用 R 来处理 sql 到 csv 的迁移?考虑一个完整的 SQL 解决方案并将处理留在数据库引擎上。具体来说,加入 Postcodes 表和 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两个表之间的或关系。但是,SQL 也允许笛卡尔积或交叉连接(对于看似不相关的表),其中查询返回列出的表之间的总组合集。您可以通过某些过滤子句使用 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 = "..."
于 2016-01-08T03:09:00.513 回答