为什么在使用SQLSave保存到ms sql时,RODBC会丢失我的数字列的精度?
在R中,我用一个数值列创建了下面的dataframe。它们可能看起来已经四舍五入了,但这是一个印刷问题,它们不是四舍五入的。
>test <- data.frame(
id=c(1,2,3),
numbers=c(12345678.90,12345678.91,12345678.92)
)
> str(test)
'data.frame': 3 obs. of 2 variables:
$ id : num 1 2 3
$ numbers: num 12345679 12345679 12345679
> test$numbers==123456789
[1] FALSE FALSE FALSE
将其保存到数据库中,似乎表明丢失了某些精度:
> dbconn <- odbcDriverConnect("driver={SQL Server};server=HOSTNAME\\SQL2014;database=test_db;trusted_connection=true")
> sqlSave(dbconn, test, fast=F, verbose=T)
Query: CREATE TABLE "test" ("rownames" varchar(255), "id" float, "numbers" float)
Query: INSERT INTO "test" ( "rownames", "id", "numbers" ) VALUES ( '1', 1, 12345679 )
Query: INSERT INTO "test" ( "rownames", "id", "numbers" ) VALUES ( '2', 2, 12345679 )
Query: INSERT INTO "test" ( "rownames", "id", "numbers" ) VALUES ( '3', 3, 12345679 )
> test2<-sqlFetch(dbconn, "test")
> test2
id numbers
1 1 12345679
2 2 12345679
3 3 12345679
> test2$numbers==12345679
[1] TRUE TRUE TRUE
> as.character(test$numbers)
[1] "12345678.9" "12345678.91" "12345678.92"
Date类列会导致float类型的ms sql列,从而导致存储不正确的值:
> test <- data.frame(id=c(1,2,3),date=as.Date(c("2014-12-21","2014-12-22","2014-12-23")))
> sqlSave(dbconn, test, fast=F, verbose=T)
Query: CREATE TABLE "test" ("rownames" varchar(255), "id" float, "date" float)
Query: INSERT INTO "test" ( "rownames", "id", "date" ) VALUES ( '1', 1, 2014-12-21 )
Query: INSERT INTO "test" ( "rownames", "id", "date" ) VALUES ( '2', 2, 2014-12-22 )
Query: INSERT INTO "test" ( "rownames", "id", "date" ) VALUES ( '3', 3, 2014-12-23 )
> test2<-sqlFetch(dbconn, "test")
> test2
id date
1 1 1981
2 2 1980
3 3 1979
日期被解释为一个公式:
> 2014-12-21
[1] 1981
> packageVersion("RODBC")
[1] ‘1.3.10’
在RODBC的代码中,似乎存在在as.matrix.dataframe内取消列表的内部调用,这可以解释这个问题:
> unlist(list(test))
id1 id2 id3 numbers1 numbers2 numbers3
1 2 3 12345679 12345679 12345679 '
我最好的客人是围绕RODBC工作,并作为varType逻辑控制到字符的转换。
逻辑列被解释为varchar,我们可以很容易地将其转换为bit
sqlSave2<-function(dbconn, dat, tablename = NULL, ...){
# get the name of the variable passed as dat, taken from sqlSave implementation
if (is.null(tablename))
tablename <- if (length(substitute(dat)) == 1)
as.character(substitute(dat))
else as.character(substitute(dat)[[2L]])
if (length(tablename) != 1L)
stop(sQuote(tablename), " should be a name")
varTypes <- sapply(dat, function(x){
if(is.numeric(x)){
"float"
}else if(is.factor(x)|is.character(x)){
paste0("[varchar](",max(nchar(as.character(x))),")")
} else if(is.logical(x)){"BIT"} else if("Date"%in%class(x)) {
"date"
} else if ("POSIXt"%in%class(x)){
"smalldatetime"
}else{NA}})# let RODBC determine
varTypes <- varTypes[!is.na(varTypes)]
dat2<-as.data.frame(sapply(dat, function(x){
if(is.numeric(x)){
x2<-sprintf("%.15e",x)
if(sum(is.na(x))>0)
x2[is.na(x)]<-NA
x2
} else if(is.logical(x)){
x2<-rep(0,length(x))
x2[!is.na(x) & x==T]<-1
if(sum(is.na(x))>0)
x2[is.na(x)] <- NA
x2
} else as.character(x)
}))
sqlSave(dbconn, dat2, tablename, fast=FALSE, varTypes=varTypes, ...)
}
> test <- data.frame(
id=c(123456789.12,123456789.23,123456789.23),
date=as.Date(c("2014-12-21","2014-12-22","2014-12-23")),
datetime=as.POSIXlt(c("2014-12-21 10:00","2014-12-22 11:00","2014-12-23 12:00")))
> str(test)
'data.frame': 3 obs. of 3 variables:
$ id : num 1.23e+08 1.23e+08 1.23e+08
$ date : Date, format: "2014-12-21" "2014-12-22" "2014-12-23"
$ datetime: POSIXct, format: "2014-12-21 10:00:00" "2014-12-22 11:00:00" "2014-12-23 12:00:00"
> sqlSave(dbconn, test, fast=F, verbose=T)
Query: CREATE TABLE "test" ("rownames" varchar(255), "id" float, "date" float, "datetime" float)
Query: INSERT INTO "test" ( "rownames", "id", "date", "datetime" ) VALUES ( '1', 123456789, 2014-12-21, 2014-12-21 10:00:00 )
Error in sqlSave(dbconn, test, fast = F, verbose = T) :
42000 102 [Microsoft][ODBC SQL Server Driver][SQL Server]Incorrect syntax near '10'.
[RODBC] ERROR: Could not SQLExecDirect 'INSERT INTO "test" ( "rownames", "id", "date", "datetime" ) VALUES ( '1', 123456789, 2014-12-21, 2014-12-21 10:00:00 )'
> sqlSave2(dbconn, test)
Query: CREATE TABLE "test" ("rownames" varchar(255), "id" float, "date" date, "datetime" smalldatetime)
Query: INSERT INTO "test" ( "rownames", "id", "date", "datetime" ) VALUES ( '1', 1.234567891200000e+08, N'2014-12-21', '2014-12-21 10:00:00' )
Query: INSERT INTO "test" ( "rownames", "id", "date", "datetime" ) VALUES ( '2', 1.234567892300000e+08, N'2014-12-22', '2014-12-22 11:00:00' )
Query: INSERT INTO "test" ( "rownames", "id", "date", "datetime" ) VALUES ( '3', 1.234567892300000e+08, N'2014-12-23', '2014-12-23 12:00:00' )
> test2<-sqlFetch(dbconn, "test")
> test2
id date datetime
1 123456789 2014-12-21 2014-12-21 10:00:00
2 123456789 2014-12-22 2014-12-22 11:00:00
3 123456789 2014-12-23 2014-12-23 12:00:00
> str(test2)
'data.frame': 3 obs. of 3 variables:
$ id : num 1.23e+08 1.23e+08 1.23e+08
$ date : Factor w/ 3 levels "2014-12-21","2014-12-22",..: 1 2 3
$ datetime: POSIXct, format: "2014-12-21 10:00:00" "2014-12-22 11:00:00" "2014-12-23 12:00:00"
> test2$id==123456789
[1] FALSE FALSE FALSE
我正在为一个由5个表和近10年的数据组成的SQL数据库创建一个缺失矩阵。我已经建立了ODBC连接,并且正在使用R中的RODBC包作为我的工作环境。我试图编写一个函数,该函数将输出每个表每年的行数、给定表在给定年份的空值(不存在的值)的计数和百分比以及给定表的缺失值(跳过的问题/未回答的问题)的计数和百分比。我写了下面的代码,试图让它在一个变量上工作,然后在它工作后将它变成一个函数。但是,当我运行这
问题内容: 我在ResultSet.getDate(x)调用中失去了精度。基本上: 返回的日期被截断为MODIFIED是默认精度的Oracle TIMESTAMP字段的日期。我认为可能缺少一些JDBC调整;通常,TIMESTAMP与DATE兼容,但我希望不必重新定义整个表。 问题答案: 传回,而不是。它被定义为一个永恒的日期。如果需要时间戳记,请使用!
问题内容: 下面给出测试代码及其输出。当我从数字值中获得浮点值时,精度就会丢失..谁能告诉我为什么这种行为以及如何处理呢? 输出: 还为什么float值小于Float.MAX_VALUE? 问题答案: 我爱这些。但我会使其快速而轻松地进行。 浮点数和小数(也称为浮点数)也不会精确地保留在内存中。但我不想在这里涉及浮点精度与精度问题,我只将您指向一个链接-http: //www.cygnus- so
当我将Object转换为Json时,我遇到了大十进制精度丢失的问题。 假设我有Pojo类, 现在我将值设置为Pojo,然后转换为JSON 第一次测试-正确输出 第二次测试-输出错误(失去BigDecimal精度) 第三次测试-输出错误(失去BigDecimal精度) 令人惊讶的是,每当BigDecimal值的长度更大时,它也会截断小数点。json转换有什么问题。你能给我提供解决方案吗?
在使用时,精度会下降,高达几分钟。例如:
我用熊猫组织了我的数据。我像下面这样填写我的程序 当我打印df2时,我可以在TRDAR_CD列中看到11947和11948值。如下图所示 之后,我使用了groupby函数,并丢失了TRDAR_CD列中的11948个值。你可以在下图中看到这种情况 TRDAR_CD_NM 1085428非空对象 SVC_INDUTY_CD 1089023非空对象 SVC_INDUTY_CD_NM 1089023非空对