代码之家  ›  专栏  ›  技术社区  ›  Yorgos

将正确的(字母)数字字段读入r

r
  •  3
  • Yorgos  · 技术社区  · 16 年前

    以制表符分隔的文本文件实际上是数据库表的导出(使用bcp),其格式为(前5列):

    102 1   01  e113c   3224.96     12  
    102 1   01  e185    101127.25   12
    102 2   01  e185    176417.90   12
    102A   3    01  e185    26261.03    12
    

    我试图用如下命令将其导入r

    data <- read.delim("C:\\test.txt", header = FALSE, sep = "\t")
    

    问题是,实际上是varchar字段(字母数字)的第三列被错误地读取为整数(因为整列中没有字母),并且前导零消失。当我使用odbcconnect直接从数据库导入数据时,也发生了同样的事情。同样,该列被读取为整数。

    str(data)
    $ code: int  1 1 1 1 1 1 6 1 1 8 ...
    

    如何在r中正确导入这样的数据集,以便在执行一些数据操作之后能够再次安全地填充db表?

    编辑

    我在read.delim中添加了以下参数

     colClasses = c("factor","integer","factor","factor","numeric","character","factor","factor","factor","factor","integer","character","factor")
    
    • 对于varchar字段,您建议使用“character”还是“factor”?

    • 用“字符”表示日期时间可以吗?

    • 我应该怎么做才能准确地读取像540912.6899999994这样的数字字段,而不是像540912.69那样?

    我想要一个尽可能自动的创造 colClasses 向量,具体取决于相关表架构中定义的数据类型。

    2 回复  |  直到 16 年前
        1
  •  4
  •   Richie Cotton Joris Meys    16 年前

    对于varchar字段,您建议使用“character”还是“factor”?

    正如约翰所说,这取决于用法。在两者之间切换很简单,所以不用太担心。如果列表示一个分类变量,则它最终应被视为 factor . 如果您打算挖掘文本(例如注释字段),则 character 更有意义。

    用“字符”表示日期时间可以吗?

    将日期存储在数据框中是可以的,但是如果您希望在分析时正确地对待它们,则必须将其转换为 Date POSIXct/POSIXlt 形式。

    我应该怎么做才能准确地读取像540912.6899999994这样的数字字段,而不是像540912.69那样?

    将值读入到通常的双精度(约15 sig图);在这个特定示例中,540912.69是您可以达到的最佳精度。比较

    print(540912.68999999994)             # 540912.7
    print(540912.68999999994, digits=22)  # 540912.69
    print(540912.6899999994)              # 540912.7
    print(540912.6899999994, digits=22)   # 540912.6899999994
    

    编辑:如果需要更精确的数字,请使用 Rmpfr 包裹。


    我希望尽可能自动地创建colclasses向量,这取决于相关表的模式中定义的数据类型。

    默认为 colClasses (当您没有指定它时)在猜测列应该是什么方面做得相当好。如果你在做像使用 01 作为一个字符,就没有办法round显式地指定它。

        2
  •  1
  •   John    16 年前

    性格和因素的问题只有你能回答。这取决于以后是否需要将它们用作因子或字符。这还取决于你是否需要在事后把它们清理干净。例如,如果您计划在之后对某个因子应用一些ifelse()修改,那么您现在不妨将其作为字符读入,稍后再将其转换为因子。或者,如果你想以某种方式对这个因素进行特殊编码,你最好把它作为字符读入。

    另外,在read.table上使用read.delim的原因是因为默认设置,因此不必费心将sep设置为与默认设置相同。