Handling field types in database interaction with R -
i use rmysql , mysql database store datasets. data gets revised or store results database well. long story short, there quite interaction between r , database in use case.
most of time use convenience functions dbwritetable
, dbreadtable
to write , read data. unfortunately these ignoring r data types , mysql field types. mean expect mysql date fields end in date
or posix
class. other way around i´d think these r classes stored corresponding mysql field type. means date should not character – i not expect distinguish between float , doubles here...
i tried use dbgetquery
– same result there. there have missed when reading manual or not possible (yet) in these packages? nice work around?
edit: @mdsummer tried find more in documentation, found these disappointing lines: `mysql tables read r data.frames, without coercing character or logical data factors. while exporting data.frames, factors exported character vectors.
integer columns imported r integer vectors, except cases such bigint or unsigned integer coerced r's double precision vectors avoid truncation (currently r's integers signed 32-bit quantities).
time variables imported/exported character data, need convert these favorite date/time representation.
ok, got working solution now. here's function maps mysql field types r classes. helps in particular handling mysql field type date...
dbreadmap <- function(con,table){ statement <- paste("describe ",table,sep="") desc <- dbgetquery(con=con,statement)[,1:2] # strip row_names if exists because it's attribute , not real column # otherweise causes problems row count if table has 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 returned describe desc[,2] <- gsub("[^a-z]","",desc[,2]) # building 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) }
maybe not programming practice – i don't know better. so, use @ own risk or me improve it... , of course it's half of it: reading
. i´ll find time write writing function soon.
if have suggestions mapping dictionary let me know :)
Comments
Post a Comment