导入包含逗号、千位分隔符和尾随减号的 CSV 数据

Posted

技术标签:

【中文标题】导入包含逗号、千位分隔符和尾随减号的 CSV 数据【英文标题】:Importing CSV data containing commas, thousand separators and trailing minus sign 【发布时间】:2011-07-19 17:58:11 【问题描述】:

Mac OS X 上的 R 2.13.1。我正在尝试导入一个数据文件,其中包含一个点作为千位分隔符和逗号作为小数点,以及尾随负数的减号。

基本上,我正在尝试转换:

"A|324,80|1.324,80|35,80-"

  V1    V2     V3    V4
1  A 324.80 1324.8 -35.80

现在,以下两项都可以交互:

gsub("\\.","","1.324,80")
[1] "1324,80"

gsub("(.+)-$","-\\1", "35,80-")
[1] "-35,80"

并将它们组合起来:

gsub("\\.", "", gsub("(.+)-$","-\\1","1.324,80-"))
[1] "-1324,80"

但是,我无法从 read.data 中删除千位分隔符:

setClass("num.with.commas")

setAs("character", "num.with.commas", function(from) as.numeric(gsub("\\.", "", sub("(.+)-$","-\\1",from))) )
mydata <- "A|324,80|1.324,80|35,80-"

mytable <- read.table(textConnection(mydata), header=FALSE, quote="", comment.char="", sep="|", dec=",", skip=0, fill=FALSE,strip.white=TRUE, colClasses=c("character","num.with.commas", "num.with.commas", "num.with.commas"))

Warning messages:
1: In asMethod(object) : NAs introduced by coercion
2: In asMethod(object) : NAs introduced by coercion
3: In asMethod(object) : NAs introduced by coercion

mytable
  V1 V2 V3 V4
1  A NA NA NA

请注意,如果我从“\\.”更改到","函数中,事情看起来有点不同:

setAs("character", "num.with.commas", function(from) as.numeric(gsub(",", "", sub("(.+)-$","-\\1",from))) )

mytable <- read.table(textConnection(mydata), header=FALSE, quote="", comment.char="", sep="|", dec=",", skip=0, fill=FALSE,strip.white=TRUE, colClasses=c("character","num.with.commas", "num.with.commas", "num.with.commas"))

mytable
  V1    V2     V3    V4
1  A 32480 1.3248 -3580

我认为问题在于带有 dec="," 的 read.data 将传入的 "," 转换为 "."在调用 as(from, "num.with.commas") 之前,输入字符串可以是例如“1.324.80”。

我希望 as("1.123,80-","num.with.commas") 返回 -1123.80 和 as("1.100.123,80", "num.with.commas") 返回 1100123.80。

如何让我的 num.with.commas 替换输入字符串中的所有除了最后一个小数点?

更新:首先,我添加了负前瞻并让 as() 在控制台中工作:

setAs("character", "num.with.commas", function(from) as.numeric(gsub("(?!\\.\\d\\d$)\\.", "", gsub("(.+)-$","-\\1",from), perl=TRUE)) )
as("1.210.123.80-","num.with.commas")
[1] -1210124
as("10.123.80-","num.with.commas")
[1] -10123.8
as("10.123.80","num.with.commas")
[1] 10123.8

但是,read.table 仍然存在同样的问题。在我的函数中添加一些 print() 表明 num.with.commas 实际上得到了逗号而不是重点。

所以我目前的解决方案是将“,”替换为“。”在 num.with.commas 中。

setAs("character", "num.with.commas", function(from) as.numeric(gsub(",","\\.",gsub("(?!\\.\\d\\d$)\\.", "", gsub("(.+)-$","-\\1",from), perl=TRUE))) )
mytable <- read.table(textConnection(mydata), header=FALSE, quote="", comment.char="", sep="|", dec=",", skip=0, fill=FALSE,strip.white=TRUE, colClasses=c("character","num.with.commas", "num.with.commas", "num.with.commas"))
mytable
  V1    V2      V3    V4
1  A 324.8 1101325 -35.8

【问题讨论】:

【参考方案1】:

您应该先删除所有句点,然后将逗号更改为小数点,然后再使用 as.numeric() 进行强制。您可以稍后使用 options(OutDec=",") 控制小数点的打印方式。我不认为 R 在内部使用逗号作为小数分隔符,即使在它们是常规的语言环境中也是如此。

> tst <- c("A","324,80","1.324,80","35,80-")
> 
> as.numeric( sub("\\,", ".", sub("(.+)-$","-\\1", gsub("\\.", "", tst)) ) )
[1]     NA  324.8 1324.8  -35.8
Warning message:
NAs introduced by coercion 

【讨论】:

【参考方案2】:

这是一个带有正则表达式和替换的解决方案

mydata <- "A|324,80|1.324,80|35,80-"
# Split data
mydata2 <- strsplit(mydata,"|",fixed=TRUE)[[1]]
# Remove commas
mydata3 <- gsub(",","",mydata2,fixed=TRUE)
# Move negatives to front of string
mydata4 <- gsub("^(.+)-$","-\\1",mydata3)
# Convert to numeric
mydata.cleaned <- c(mydata4[1],as.numeric(mydata4[2:4]))

【讨论】:

谢谢,gsk3。这和我最先阅读的 DWin 的答案基本相同。 不用担心。很高兴您得到了一些解决您问题的答案。

以上是关于导入包含逗号、千位分隔符和尾随减号的 CSV 数据的主要内容,如果未能解决你的问题,请参考以下文章

删除逗号,它是 R 中的千位分隔符

读取所有列合并为一个的csv文件:千位逗号问题

当某些行包含逗号作为千位分隔符和“标志并且没有小数的行没有标志时如何在R中读取数据

如何读取包含千位分隔符和零的特殊处理(在 R 中)的 .csv 数据?

如何使用逗号将数字转换为千位分隔符? [复制]

导入包含引号中的逗号的字段的 CSV 文件?