首页 文章

read.csv返回的data.frame中的所有因素是否仅来自字符数据?

提问于
浏览
2

我对 read.csv 中的数据帧行为感到好奇,目的是为了在一些算法工作中做一些数据完整性检查以尽早失败我们猜测不是,但是documentation我只看到字符数据与因子之间的关系但是没有其他类型,让我感到厌倦,我可能正在做出反向错误 .

R- data.frame文档

stringsAsFactors logical:字符向量应该转换为因子吗? 'factory-fresh'默认值为TRUE,但可以通过设置选项(stringsAsFactors = FALSE)来更改 .

基本上我打算检查的东西会是这样的

if ( any( sapply( myCsvDataFrame, class ) == "factor" ) ) {
   stop("DataIntegrityError--dataframe contains character data")
}

进一步documentation似乎支持我的猜测:

除非指定了colClasses,否则所有列都将作为字符列读取,然后根据需要使用type.convert转换为逻辑,整数,数字,复数或(取决于as.is)因子 . 报价(默认情况下)在所有字段中解释,因此像“42”这样的值列将产生整数列 .

所以这解释了更多的行为

as.is.read的默认行为是将字符变量(未转换为逻辑,数字或复数)转换为因子 . 变量as.is控制colClasses未另行指定的列的转换 . 它的值可以是逻辑向量(如果需要,可以回收值),也可以是数字或字符索引的向量,用于指定哪些列不应转换为因子 . 注意:要取消包括数字列的所有转换,请设置colClasses =“character” . 请注意,as.is是按列(而不是每个变量)指定的,因此包括行名称列(如果有)和要跳过的任何列 .

我从这一切中拿走的是R首先将所有内容加载为字符(这在CSV上下文中是有意义的,只是一个平面文本文件)然后尝试强制/将某些列转换为数字/逻辑类型并且仅这种转换不成功的地方是左列,它们仍然作为字符数据,随后存储在因子中,成为我们在结果数据框中看到的内容 .

1 回答

  • 1

    在Richard Scriven的评论的基础上, read.table (及其包装函数)可以创建一个包含五种类型列的data.frame:

    • 逻辑

    • 整数

    • 数字

    • 字符或因子(取决于 stringsAsFactors 参数/选项)

    • 复杂

    这是一个简单的例子,显示了这五种类型的数据:

    str(read.csv(text = "a,b,c,d,e
    TRUE,1,4.0,a,1i
    FALSE,2,5.5,b,2i
    TRUE,3,6.0,c,3i", header = TRUE))
    # 'data.frame':   3 obs. of  5 variables:
    #  $ a: logi  TRUE FALSE TRUE
    #  $ b: int  1 2 3
    #  $ c: num  4 5.5 6
    #  $ d: Factor w/ 3 levels "a","b","c": 1 2 3
    #  $ e: cplx  0+1i 0+2i 0+3i
    

    请注意第四列是一个字符列,作为一个因子读入 . 每个列都作为字符向量读入,并使用 colClasses 参数或通过 type.convert 进行自动类型检查(在您的问题中突出显示)强制转换为特定类 .

    这意味着一切都是一个角色,除非R能够发现它是其他东西 . 如果 stringsAsFactors = TRUE ,那么这些列将作为因子返回 .

    这应该是非常直观的,除了正如理查德斯克里文所指出的那样,当 type.convert 无法找出一列时,你有时会被 grab . 以下是一些示例,所有这些都是拼写错误或列形状不良的结果:

    • 混合逻辑表示(期望逻辑,获取因子):
    str(read.csv(text = "a
    TRUE
    FALSE
    1
    0", header = TRUE))
    # 'data.frame':   4 obs. of  1 variable:
    #  $ a: Factor w/ 4 levels "0","1","FALSE",..: 4 3 2 1
    
    • 否则为数字列中的字符串(期望整数,获取因子):
    str(read.csv(text = "a
    1
    2
    3
    4a", header = TRUE))
    # 'data.frame':   4 obs. of  1 variable:
    #  $ a: Factor w/ 4 levels "1","2",..: 1 2 3 4
    
    • 数字列中的另一个字符串示例(期望数字,获取因子):
    str(read.csv(text = "a
    1.1
    2.1
    3.1
    4.x", header = TRUE))
    # 'data.frame':   4 obs. of  1 variable:
    #  $ a: Factor w/ 4 levels "1.1","2.1",..: 1 2 3 4
    
    • 说实际上没有 Headers (期望整数,得到因子):
    str(read.csv(text = "a
    1
    2
    3
    4a", header = FALSE))
    # 'data.frame':   5 obs. of  1 variable:
    #  $ V1: Factor w/ 5 levels "1","2",..: 5 1 2 3 4
    
    • 数值中的意外空格(期望数字,获取因子):
    str(read.csv(text = "a
    1
    2
    3 .4", header = FALSE))
    # 'data.frame':   3 obs. of  1 variable:
    #  $ a: Factor w/ 3 levels "1","2","3 . 4",..: 1 2 3
    
    • R 3.1.0中,如果在数字列中读取会导致精度损失(因为该列包含太多小数位以表示在R中),也可能最终得到因子列 . 现在可以在 read.tablenumerals 参数中看到此行为:
    # default behavior (expect numeric, get numeric)
    str(read.csv(text = "a
    1.1
    2.2
    3.123456789123456789", header = TRUE, numerals = "allow.loss"))
    # 'data.frame':   3 obs. of  1 variable:
    #  $ a: num  1.1 2.2 3.12
    
    # "no.loss" argument (expect numeric, get factor)
    str(read.csv(text = "a
    1.1
    2.2
    3.123456789123456789", header = TRUE, numerals = "no.loss"))
    # 'data.frame':   3 obs. of  1 variable:
    #  $ a: Factor w/ 3 levels "        1.1",..: 1 2 3
    

    可能还有一些其他情况会导致接收到一个因子列,但所有这些情况都是由于格式错误的文件或 read.table 使用不当的参数造成的 .

相关问题