10

RMySQLとMySQLデータベースを使用してデータセットを保存しています。データが改訂されたり、結果がデータベースに保存されたりすることがあります。簡単に言えば、私のユースケースでは、Rとデータベースの間にかなりの相互作用があります。

ほとんどの場合、データの書き込みと読み取りには、やdbWriteTableなどの便利な関数を使用します。dbReadTable残念ながら、これらはRデータ型とMySQLフィールド型を完全に無視しています。つまり、MySQLの日付フィールドは最終的にDateまたはPOSIXクラスになると思います。逆に言えば、これらのRクラスはある程度対応するMySQLフィールドタイプとして格納されていると思います。つまり、日付は文字であってはなりません–ここでfloatとdoubleを区別することは期待していません...

私も使用しようとしましたdbGetQuery–同じ結果があります。マニュアルを読んだときに完全に見逃したものはありますか、それともこれらのパッケージでは(まだ)不可能ですか?うまく回避するにはどうすればよいですか?

編集:@mdsummerドキュメントでもっと何かを見つけようとしましたが、これらの残念な行だけが見つかりました: `MySQLテーブルはdata.framesとしてRに読み込まれますが、文字または論理データを強制的に要素に変換することはありません。同様に、data.framesをエクスポートする場合、ファクターは文字ベクトルとしてエクスポートされます。

整数列は通常、Rの倍精度ベクトルに強制されて切り捨てを回避するBIGINTやUNSIGNED INTEGERなどの場合を除いて、Rの整数ベクトルとしてインポートされます(現在、Rの整数は32ビットの符号付きの量です)。

時間変数は文字データとしてインポート/エクスポートされるため、これらをお気に入りの日付/時刻表現に変換する必要があります。

4

2 に答える 2

5

わかりました、私は今実用的な解決策を手に入れました。これは、MySQLフィールドタイプをRクラスにマップする関数です。これは、特にMySQLフィールドタイプの日付の処理に役立ちます...

dbReadMap <- function(con,table){
    statement <- paste("DESCRIBE ",table,sep="")
    desc <- dbGetQuery(con=con,statement)[,1:2]

  # strip row_names if exists because it's an attribute and not real column
  # otherweise it causes problems with the row count if the table has a row_names col
  if(length(grep(pattern="row_names",x=desc)) != 0){
  x <- grep(pattern="row_names",x=desc)
  desc <- desc[-x,]
  }



    # replace length output in brackets that is returned by describe
    desc[,2] <- gsub("[^a-z]","",desc[,2])

    # building a dictionary 
    fieldtypes <- c("int","tinyint","bigint","float","double","date","character","varchar","text")
    rclasses <- c("as.numeric","as.numeric","as.numeric","as.numeric","as.numeric","as.Date","as.character","as.character","as.character") 
    fieldtype_to_rclass = cbind(fieldtypes,rclasses)

    map <- merge(fieldtype_to_rclass,desc,by.x="fieldtypes",by.y="Type")
    map$rclasses <- as.character(map$rclasses)
    #get data
    res <- dbReadTable(con=con,table)



    i=1
    for(i in 1:length(map$rclasses)) {
        cvn <- call(map$rclasses[i],res[,map$Field[i]])
        res[map$Field[i]] <- eval(cvn)
    }


    return(res)
}

たぶん、これは良いプログラミング慣行ではありません–私はそれ以上のことを知りません。だから、あなた自身の責任でそれを使うか、私がそれを改善するのを手伝ってください...そしてもちろんそれはそれの半分だけです:reading。うまくいけば、私はすぐに書き込み関数を書く時間を見つけるでしょう。

マッピング辞書についての提案があれば、私に知らせてください:)

于 2011-02-23T21:08:20.383 に答える
1

Matt Bannertこれは、テーブルの代わりにクエリで機能する@関数のより一般的な関数です。

# Extension to dbGetQuery2 that understands MySQL data types
dbGetQuery2 <- function(con,query){
    statement <- paste0("CREATE TEMPORARY TABLE `temp` ", query)
    dbSendQuery(con, statement)
    desc <- dbGetQuery(con, "DESCRIBE `temp`")[,1:2]
    dbSendQuery(con, "DROP TABLE `temp`")

    # strip row_names if exists because it's an attribute and not real column
    # otherweise it causes problems with the row count if the table has a row_names col
    if(length(grep(pattern="row_names",x=desc)) != 0){
        x <- grep(pattern="row_names",x=desc)
        desc <- desc[-x,]
    }

    # replace length output in brackets that is returned by describe
    desc[,2] <- gsub("[^a-z]","",desc[,2])

    # building a dictionary 
    fieldtypes <- c("int",        "tinyint",    "bigint",     "float",      "double",     "date",    "character",    "varchar",   "text")
    rclasses <-   c("as.numeric", "as.numeric", "as.numeric", "as.numeric", "as.numeric", "as.Date", "as.character", "as.factor", "as.character") 
    fieldtype_to_rclass = cbind(fieldtypes,rclasses)

    map <- merge(fieldtype_to_rclass,desc,by.x="fieldtypes",by.y="Type")
    map$rclasses <- as.character(map$rclasses)
    #get data
    res <- dbGetQuery(con,query)

    i=1
    for(i in 1:length(map$rclasses)) {
        cvn <- call(map$rclasses[i],res[,map$Field[i]])
        res[map$Field[i]] <- eval(cvn)
    }

    return(res)
}
于 2015-01-08T08:37:29.430 に答える