【发布时间】:2012-10-01 05:35:10
【问题描述】:
我正在尝试将 SQLite 数据库中的表写入 R 数据框,但遇到了一个让我难过的问题。这是我要导入的 SQLite 表中的前三个条目:
1|10|0|0|0|0|10|10|0|0|0|6|8|6|20000|30000|2012-02-29 21:27:07.239091|2012-02-29 21:28:24.815385|6|80.67.28.161|||||||||||||||||||||||||||||||33|13.4936||t|t|f||||||||||||||||||4|0|0|7|7|2
2|10|0|0|0|0|0|0|0|2|2|4|5|4|20000|30000|2012-02-29 22:00:30.618726|2012-02-29 22:04:09.629942|5|80.67.28.161|3|7||0|1|3|0|||4|3|4|5|5|5|5|4|5|4|4|0|0|0|0|0|9|9|9|9|9|||1|f|t|f|||||||||||||k|text|l|||-13|0|3|10||2
3|13|2|4|4|4|4|1|1|2|5|6|3|2|40000|10000|2012-03-01 09:07:52.310033|2012-03-01 09:21:13.097303|6|80.67.28.161|2|2||30|1|1|0|||4|2|1|6|8|3|5|6|6|7|6|||||||||||26|13.6336|4|f|t|f|t|f|f|f|f|||||||||some text||||10|1|1|3|2|3
我感兴趣的是第 53 到 60 列,为了省去您在上面计算的麻烦,它们看起来像这样:
|t|t|f||||||
|f|t|f||||||
|f|t|f|t|f|f|f|f|
如您所见,对于前两个条目,只有前三个列不为 NULL,而对于第三个条目,所有八列都分配了值。
这是这些列的 SQLite 表信息
sqlite> PRAGMA table_info(observations);
0|id|INTEGER|1||1
** snip **
53|understanding1|boolean|0||0
54|understanding2|boolean|0||0
55|understanding3|boolean|0||0
56|understanding4|boolean|0||0
57|understanding5|boolean|0||0
58|understanding6|boolean|0||0
59|understanding7|boolean|0||0
60|understanding8|boolean|0||0
** snip **
现在,当我尝试将其读入 R 时,这些相同的列最终会变成:
> library('RSQLite')
> con <- dbConnect("SQLite", dbname = 'db.sqlite3))
> obs <- dbReadTable(con,'observations')
> obs[1:3,names(obs) %in% paste0('understanding',1:8)]
understanding1 understanding2 understanding3 understanding4 understanding5 understanding6 understanding7
1 t t f NA NA NA NA
2 f t f NA NA NA NA
3 f t f 0 0 0 0
understanding8
1 NA
2 NA
3 0
如您所见,前三列包含的值是't' 或'f',其他列是NA,其中SQLite 表中的对应值是NULL 和0 它们不是 - 无论 SQLite 表中的相应值是 t 还是 f。不用说,这不是我所期望的行为。我认为问题是这些列的类型转换不正确:
> sapply(obs[1:3,names(obs) %in% paste0('understanding',1:8)], class)
understanding1 understanding2 understanding3 understanding4 understanding5 understanding6 understanding7
"character" "character" "character" "numeric" "numeric" "numeric" "numeric"
understanding8
"numeric"
可能是 RSQLite 将前三列设置为 character 类型,因为在第一个条目的相应列中看到 t 和 f 作为值但与 numeric 一起使用,因为在这些列中的第一个条目恰好是 NULL?
如果确实发生了这种情况,有没有办法解决这个问题并将所有这些列转换为character(或者更好的是logical)?
【问题讨论】:
-
我对 SQLite 的了解有限,但我对你如何将字符
t和`f存储在 SQLite 的布尔列中感到困惑。我的理解是 SQLite 没有原生的布尔类型,它只是将它们存储为整数 0 和 1。此外,不强制列类型,所以如果您将文本插入布尔字段,SQLite 将转换存储模式列。 -
我也不是 SQLite 专家(我不知道没有强制执行列类型)。整个数据库来自一个 Ruby on Rails Web 应用程序,我几乎必须按原样接受它。但是,如果问题是列类型没有被强制执行——而且 RSQLite 显然不只是使用列类型的 R 等效项——那么 RSQLite 如何推断要分配给每一列的类以及有什么方法可以影响它推理?
-
我不确定;我在 RSQLite 的文档中找不到描述(但真正的答案可能隐藏在 DBI 包的文档中)。 R-SIG-DB 上的一些人肯定知道 RSQLite 如何进行类型转换的细节。但在你问之前,我还会仔细检查你的数据库,并绝对确保你在只有 NA 和 0 的列中同时具有 t 和 f 值,因为这听起来很奇怪。
-
我刚刚再次检查过,据我所知,情况确实如此。感谢您的指点。我会和 R-SIG-DB 上的人一起讨论这个问题
-
我对如何进行类型转换的怀疑确实是正确的(stat.ethz.ch/pipermail/r-help/2011-March/270389.html),所以我一直在尝试按照上述文章的建议来简单地替换这些列中的每个
NULL使用'NA',然后从那里获取。但是,我很乐意以一种不会永久更改 SQLite DB 的方式来执行此操作。有没有办法运行INSERT查询来替换NULLs,将表读入R,然后恢复INSERT?