【问题标题】:R: respect quotes around numbers (treat as character) with read.csv()?R:使用 read.csv() 尊重数字周围的引号(视为字符)?
【发布时间】:2014-05-20 08:46:03
【问题描述】:

我有一个 .csv 文件,其中包含 00xxxx 形式的帐号代码,我需要它们保持这种状态,以便与使用这种格式帐号代码的其他程序一起使用。我只是在编写一个 R 脚本来核对周五的帐户费用,并且 发誓 as.is = T 正在为我工​​作。现在看来,不是。以下是一些示例数据:

test <- data.frame(col1 = c("apple", "banana", "carrot"),
                   col2 = c(100, 200, 300),
                   col3 = c("00234", "00345", "00456"))

我的write.table 策略:

write.table(test, file = "C:/path/test.csv", quote = T,
            sep=",", row.names = F)

删除旧的data.frame 并重新阅读:

rm(test)
test <- read.csv("C:/path/test.csv")
test

    col1 col2 col3
1  apple  100  234
2 banana  200  345
3 carrot  300  456

如果不清楚,它应该看起来像我们创建的原始data.frame

test
    col1 col2  col3
1  apple  100 00234
2 banana  200 00345
3 carrot  300 00456

在仔细阅读可用的read.table 选项后,我还尝试了以下方法,结果与上述相同:

test <- read.csv("C:/path/test.csv", quote = '"')
test <- read.csv("C:/path/test.csv", as.is = T)
test <- read.csv("C:/path/test.csv", as.is = T, quote = '"')

StringsAsFactors 在这种情况下似乎不相关(听起来as.is 会做同样的事情。

当我在 Emacs 中打开文件时,col3 确实被引号包围,所以我希望它被视为文本而不是转换为数字:

大多数其他问题只是关于不处理因素之类的事情,或者让数字被识别为字符,通常是该列中忽略字符串的结果。

我知道我可以从this one 之类的问题中寻求colClasses 的论点,但我不想这样做;我的“colClasses”内置在数据中:) 引用 = 字符,不引用 = 数字。

【问题讨论】:

    标签: r csv formatting


    【解决方案1】:

    ping了几个R用户的朋友后,他们都建议使用colClasses。发现不需要指定每个类,我松了一口气,因为我的数据大约是 25 列。所以确认了这一点(一旦我知道我在寻找什么)in another question

    test <- read.csv("C:/path/test.csv", colClasses = c(col3 = "character"))
    test
    
        col1 col2  col3
    1  apple  100 00234
    2 banana  200 00345
    3 carrot  300 00456
    

    就目前的情况而言,就解决方案而言,这个问题与另一个问题是重复的。不同之处在于我正在寻找 other 而非 colClasses 的方法(因为 as.is 听起来很可能是候选人),而那个问题是关于 如何 使用 @ 987654326@.

    我会重申,我实际上并不喜欢这种解决方案,即使认为它非常简单。引号表示 .csv 中的文本字段,在这种情况下,它们似乎不受尊重。 LibreOffice .csv 导入有一个“将引用的字段视为文本”复选框,我认为这类似于 R 中的as.is = T。显然不是! #end_rant

    【讨论】:

    • 其他解决方案对我不起作用,但这个解决方案可以。
    【解决方案2】:

    我也有这个问题。当然你可以手动指定 colClasses,但是为什么在引用数据时需要这样做呢?我同意 OP 在回答他自己的问题时的“咆哮”:

    引号表示 .csv 中的文本字段,但它们似乎不是 在这种情况下受到尊重。

    无论如何,我选择使用 data.table 的fread() 没有这个问题。不过,read.csv 的行为仍然很烦人。

    # here's a data frame with chr and int columns
    my_df <- data.frame(chars=letters[1:5],
                        nums=1:5,
                        txt_nums=sprintf('%02d', 1:5),
                        stringsAsFactors=F)
    
    # all looks as it should
    lapply(my_df, class)
    
    # $chars
    # [1] "character"
    # 
    # $nums
    # [1] "integer"
    # 
    # $txt_nums
    # [1] "character"
    

    但是现在,写入 csv,重新读入,第三列被强制转换为 int!

    # quote=T redundant since that's the default, but just to be sure
    write.csv(my_df, 'my_df.csv', row.names=F, quote=T) 
    my_df2 <- read.csv('my_df.csv')
    lapply(my_df2, class)
    
    # even with as.is=TRUE, same issue
    my_df2 <- read.csv('my_df.csv', as.is=T)
    lapply(my_df2, class)
    
    # data.table's fread doesn't have this issue, at least
    library(data.table)
    my_dt <- fread('my_df.csv')
    lapply(my_dt, class)
    

    【讨论】:

    • 从 data.table 1.11.0 开始,fread 不再尊重数字值的引用:“现在检测到引用的数字数据并将其读取为数字。”
    【解决方案3】:

    我希望有更好的方法,但一种选择是使用quote=""

    test <- read.csv("C:/path/test.csv", as.is = TRUE, quote = "") 
    

    这将使引号成为值的一部分,从而为您提供:

    test
    #col1 col2  col3
    #1  apple  100 "00234"
    #2 banana  200 "00345"
    #3 carrot  300 "00456"
    

    然后您可以将它们保留为该格式,或者使用 gsub 之类的东西来删除它们:

    test$col3 <- gsub('"', '', test$col3)
    
    test
    #col1 col2  col3
    #1  apple  100 00234
    #2 banana  200 00345
    #3 carrot  300 00456
    

    您可以使用某种应用类型的函数一次对整个数据框执行 gsub:

    test <- as.data.frame(sapply(test,gsub,pattern='"',replacement=""))
    

    sapply 代码取自:R - how to replace parts of variable strings within data frame

    显然,只有当您出于其他原因不需要其他地方的引号时,此方法才会对您有用。

    【讨论】:

    • 我遇到了类似的on the R mailing list。我现在忘记了为什么,但是当我在发布这个问题之前读到它时,我厌恶这样做。在这种情况下,gsub() 在单个列上不会那么糟糕。在询问一些 R 用户(使用colClasses)的朋友后,我将发布另一个答案。感谢您的建议!
    猜你喜欢
    • 2014-02-01
    • 1970-01-01
    • 2015-09-13
    • 2018-04-16
    • 1970-01-01
    • 2016-09-19
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多