使用 sqldf 保持前导零
keeping leading zeros with sqldf
我是一个完全SQL无知的人,如果这很简单,我深表歉意..
我的数据包含一个由数字组成的 ID 列,并且在许多情况下包含前导零。我想使用 sqldf 导入数据,但这样做会丢失这些数据的前导零。有没有办法保留前导零?也许通过某种方式指定所有列都是字符 类,就像在 R 的 read.table 中一样?
由于我的工作性质,我不能分享我的数据,但我正在做这样的事情:
a <- formatC(sample(1:99, 10), width = 8, format = "d", flag = "0")
fakeDF <- data.frame(v1=a, v2=rnorm(10, 0, 1))
f1 <- tempfile()
write.table(fakeDF, file=f1, quote=FALSE, row.names=FALSE, col.names=FALSE, sep="|")
f2 <- file(f1)
mydat <- sqldf::sqldf("SELECT * FROM f2", dbname=tempfile(),
file.format=list(header=FALSE, sep="|", eol="\n", skip=1))
mydat
此外,我想补充一点,所有这些 ID 的长度都不相同。如果可能的话,我想避免在事后用零手动填充数据..
像这样使用colClasses
:
library(sqldf)
read.csv.sql(f1, header = FALSE, sep = "|", colClasses = c("character", "numeric"))
给予:
V1 V2
1 00000029 1.7150650
2 00000078 0.4609162
3 00000040 -1.2650612
4 00000085 -0.6868529
5 00000090 -0.4456620
6 00000005 1.2240818
7 00000050 0.3598138
8 00000083 0.4007715
9 00000051 0.1106827
10 00000042 -0.5558411
注意:我们使用了使用这个随机种子生成的输入文件:
set.seed(123)
a <- formatC(sample(1:99, 10), width = 8, format = "d", flag = "0")
fakeDF <- data.frame(v1=a, v2=rnorm(10, 0, 1))
f1 <- tempfile()
write.table(fakeDF, file=f1, quote=FALSE, row.names=FALSE, col.names=FALSE, sep="|")
运行 前导零的一种方法是使用 SQL 字符串函数。只需将一定数量的零设置为高于您所需的字符串长度,将其与您的实际 ID 字段连接起来,然后从最右边的字符中删除您需要的指定长度的列。下面使用 8 个字符作为字符串长度:
mydat <- sqldf::sqldf("select rightstr('0000000000000' || ID, 8) As LeadZeroID,
* from f2;",
dbname=tempfile(),
file.format=list(header=FALSE, sep="|", eol="\n", skip=1))
我是一个完全SQL无知的人,如果这很简单,我深表歉意..
我的数据包含一个由数字组成的 ID 列,并且在许多情况下包含前导零。我想使用 sqldf 导入数据,但这样做会丢失这些数据的前导零。有没有办法保留前导零?也许通过某种方式指定所有列都是字符 类,就像在 R 的 read.table 中一样?
由于我的工作性质,我不能分享我的数据,但我正在做这样的事情:
a <- formatC(sample(1:99, 10), width = 8, format = "d", flag = "0")
fakeDF <- data.frame(v1=a, v2=rnorm(10, 0, 1))
f1 <- tempfile()
write.table(fakeDF, file=f1, quote=FALSE, row.names=FALSE, col.names=FALSE, sep="|")
f2 <- file(f1)
mydat <- sqldf::sqldf("SELECT * FROM f2", dbname=tempfile(),
file.format=list(header=FALSE, sep="|", eol="\n", skip=1))
mydat
此外,我想补充一点,所有这些 ID 的长度都不相同。如果可能的话,我想避免在事后用零手动填充数据..
像这样使用colClasses
:
library(sqldf)
read.csv.sql(f1, header = FALSE, sep = "|", colClasses = c("character", "numeric"))
给予:
V1 V2
1 00000029 1.7150650
2 00000078 0.4609162
3 00000040 -1.2650612
4 00000085 -0.6868529
5 00000090 -0.4456620
6 00000005 1.2240818
7 00000050 0.3598138
8 00000083 0.4007715
9 00000051 0.1106827
10 00000042 -0.5558411
注意:我们使用了使用这个随机种子生成的输入文件:
set.seed(123)
a <- formatC(sample(1:99, 10), width = 8, format = "d", flag = "0")
fakeDF <- data.frame(v1=a, v2=rnorm(10, 0, 1))
f1 <- tempfile()
write.table(fakeDF, file=f1, quote=FALSE, row.names=FALSE, col.names=FALSE, sep="|")
运行 前导零的一种方法是使用 SQL 字符串函数。只需将一定数量的零设置为高于您所需的字符串长度,将其与您的实际 ID 字段连接起来,然后从最右边的字符中删除您需要的指定长度的列。下面使用 8 个字符作为字符串长度:
mydat <- sqldf::sqldf("select rightstr('0000000000000' || ID, 8) As LeadZeroID,
* from f2;",
dbname=tempfile(),
file.format=list(header=FALSE, sep="|", eol="\n", skip=1))