【问题标题】:keeping leading zeros with sqldf使用 sqldf 保持前导零
【发布时间】:2015-12-03 18:20:22
【问题描述】:

我是一个完全不了解 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 的长度都不相同。如果可能的话,我想避免事后手动用零填充数据..

【问题讨论】:

  • 在您的真实数据中,列 (v1) 是否以前导零存储在磁盘上?
  • @nrussell 是的。
  • 老实说,我只会使用read.table(..., colClasses = "character") 正常读取数据——或者更好的是,使用data.table::fread——然后相应地处理数据。您始终可以使用sqldf 来操作您读入的对象。
  • @nrussell 我想这样做,但问题是我的数据大小。 fread 是一个很好的选择(而且速度更快),但它会引发一个错误,我似乎无法纠正一些文件。我实际上在某些情况下使用 fread 而在其他情况下使用 sqldf 但需要同时使用两者。我有大约 20GB 的数据分布在不同的文件中。不幸的是 read.table 还不够快。
  • 您介意发布fread 抛出的错误(以及生成它的函数调用)吗?我唯一的其他建议是,如果可能的话,使用例如将您的数据(或它的副本)存储在 SQLite 文件中。 VARCHAR(12) 用于包含前导零的数字的列。然后,您可以使用sqldf 以正确的格式将数据读入 R。

标签: sql r sqldf


【解决方案1】:

像这样使用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="|")

【讨论】:

    【解决方案2】:

    运行前导零的一种方法是使用 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))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-04
      • 2023-01-26
      • 2017-03-11
      • 2018-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多