【问题标题】:Write to dataframe with %dopar% in foreach在 foreach 中使用 %dopar% 写入数据帧
【发布时间】:2014-07-22 14:19:57
【问题描述】:

我想使用一个 foreach each 循环运行一个 doParallel 后端来从带有 RMySql 包的 MySQL 数据库中获取推文。

我为要查询的每个用户 ID 创建一个到数据库的连接,然后我从该用户获取每条推文,分 200 批。如果批量大小为 0(因此没有更多推文),我会查询下一个用户 ID。

我想将信息存储在名为 tweets 的数据框中,该数据框中包含用于表示推文中标签数量的列和包含日期的列。对于每条推文,我都想知道它有多少标签,以及它是在哪个月份创建的。然后我想将数据框中的数字增加1。

那么如何为数据框中的每条推文编写结果呢?

一开始我的数据框:

| dates    | zero_ht | one_ht | two_ht | three_ht | four_ht | five_ht |
|----------|---------|--------|--------|----------|---------|---------|
| 01/01/13 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/02/13 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/03/13 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/04/13 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/05/13 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/06/13 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/07/13 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/08/13 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/09/13 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/10/13 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/11/13 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/12/13 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/01/14 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/02/14 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/03/14 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/04/14 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/05/14 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/06/14 | 0       | 0      | 0      | 0        | 0       | 0       |
| 01/07/14 | 0       | 0      | 0      | 0        | 0       | 0       |

我的代码:

x<- foreach(i=1:nrow(ids) ,.packages=c("DBI", "RMySQL"),.combine=rbind ) %dopar% {

con <- dbConnect(MySQL(), *CREDENTIALS*)

start <- 0

length <- 1
while(length > 0)
{
query <- *QUERY*
data <- dbGetQuery(con, query)

length <- nrow(data)

#print(paste("Starting at ",start,sep=""))

for(j in 1:length)
{   
    if(length==0)
    {

    }
    else{ 

    #get the number of hashtags used
    number <-   nchar((gsub("[^#]","",data$message[j])))

    #get the date the tweet was created
    date <- paste(format(as.Date(data$created_at[j]), "%Y-%m"),"-01",sep="")
    # just use it when there are less than 5 hashtags
    if(number < 5)
    {

        if(number==0)
        {


        tweets[tweets$dates==date,2] <- tweets[tweets$dates==date,2]+1


        }
        else{
            tweets[tweets$dates==date,number+1] <- tweets[tweets$dates==date,number+1]+1


        }

    }

}    
}
#increase the start by 200; to get the next 200 tweets
start <- start + 200

}
data.frame(date=date,number=number)
dbDisconnect(con) 
}

【问题讨论】:

  • 等等 - 那么这段代码当前是否不能正常工作?如果没有,您能否添加错误消息和/或描述什么不能正常工作。由于您使用的是其他人可能无法访问的数据源(个人数据库),因此您很可能需要提供很多关于您的问题的详细信息。
  • 您好,感谢您的评论。实际上没有错误消息,但推文数据框保持填充为 0。而变量 X 只包含一个带有“true”的列表
  • 嗯,老实说,我从未使用过 RMySql 或 MySQL(我使用 SQL Server 和 RODBC),但无论如何我从未尝试过并行获取 SQL 数据,因为我的直觉一直是在非并行对应场景中不会出现一些后端复杂性。我确实看到了this similar post,它可能会为您提供一些有用的信息。
  • 一般来说,我会说,除非您正在运行如此复杂的计算/过程,以至于并行化是绝对关键的,否则您应该坚持使用非并行等价物。此外,您应该尝试不并行运行相同的代码(例如%do$ instead of %dopar%)以及会发生什么 - 这样您很可能能够判断问题出在您的代码上还是只是您尝试执行的事实它是并行的。
  • 该代码适用于普通的 for 循环和使用 %do% 的 foreach 循环。但它由大量 SQL 查询组成,这使得它非常耗时。因此,以非并行方式使用此代码是可行的,但速度极慢

标签: mysql r foreach rmysql


【解决方案1】:

感谢 cmets,我可以解决问题: 列表中只有“TRUE”的原因是 foreach 循环中的最后一个命令是

dbDisconnect(con) 

当数据库连接成功关闭时,它返回“TRUE”。

所以我只需要交换最后两行并制作

data.frame(date=date,number=number)

一切正常。

问候

【讨论】:

    猜你喜欢
    • 2017-02-07
    • 2017-08-22
    • 2011-12-16
    • 1970-01-01
    • 2011-04-23
    • 2015-07-24
    • 2021-11-20
    • 2012-11-10
    • 2018-07-13
    相关资源
    最近更新 更多