我有一个CSV文件,其中某些数值表示为带有逗号的字符串,例如千分离器,例如 "1,513" 代替 1513. 。将数据读取为R的最简单方法是什么?

我可以用 read.csv(..., colClasses="character"), ,但是后来我必须从相关元素中剥离逗号,然后再将这些列转换为数字,而我找不到一种整洁的方法来做到这一点。

有帮助吗?

解决方案 3

我想使用R而不是预处理数据,因为它在修订数据时会变得更容易。遵循Shane的建议 gsub, ,我认为这就像我能做的那样整洁:

x <- read.csv("file.csv",header=TRUE,colClasses="character")
col2cvt <- 15:41
x[,col2cvt] <- lapply(x[,col2cvt],function(x){as.numeric(gsub(",", "", x))})

其他提示

不确定如何拥有 read.csv 正确解释它,但是您可以使用 gsub 取代 ",""", ,然后将字符串转换为 numeric 使用 as.numeric:

y <- c("1,200","20,000","100","12,111")
as.numeric(gsub(",", "", y))
# [1]  1200 20000 100 12111

这是 也以前在R-Help上回答 (在 Q2在这里).

另外,您可以预处理文件,例如 sed 在Unix中。

您可以读取或读取。首先创建一个新的类定义,然后创建一个转换函数,并使用SETAS函数这样的“ AS”方法将其设置为“ AS”方法:

setClass("num.with.commas")
setAs("character", "num.with.commas", 
        function(from) as.numeric(gsub(",", "", from) ) )

然后运行read.csv喜欢:

DF <- read.csv('your.file.here', 
   colClasses=c('num.with.commas','factor','character','numeric','num.with.commas'))

这个问题已经有几年了,但是我偶然发现了这个问题,这意味着也许其他人会。

readr Library / Package具有一些不错的功能。其中之一是解释“混乱”列的好方法。

library(readr)
read_csv("numbers\n800\n\"1,800\"\n\"3500\"\n6.5",
          col_types = list(col_numeric())
        )

这产生了

资料来源:本地数据框[4 x 1

  numbers
    (dbl)
1   800.0
2  1800.0
3  3500.0
4     6.5

阅读文件时的一个重要点:您要么必须进行预处理,例如上面的评论 sed, ,或者您必须处理 在读的时候. 。通常,如果您在事实之后尝试修复问题,则很难找到一些危险的假设。 (这就是为什么Flat Files首先如此邪恶的原因。)

例如,如果我没有标记 col_types, ,我会得到这个:

> read_csv("numbers\n800\n\"1,800\"\n\"3500\"\n6.5")
Source: local data frame [4 x 1]

  numbers
    (chr)
1     800
2   1,800
3    3500
4     6.5

(请注意,现在是 chr (character) 代替 numeric.)

或者,更危险的是,如果它足够长,并且大多数早期元素不包含逗号:

> set.seed(1)
> tmp <- as.character(sample(c(1:10), 100, replace=TRUE))
> tmp <- c(tmp, "1,003")
> tmp <- paste(tmp, collapse="\"\n\"")

(使最后几个元素看起来像:)

\"5\"\n\"9\"\n\"7\"\n\"1,003"

然后,您会发现阅读该逗号的麻烦!

> tail(read_csv(tmp))
Source: local data frame [6 x 1]

     3"
  (dbl)
1 8.000
2 5.000
3 5.000
4 9.000
5 7.000
6 1.003
Warning message:
1 problems parsing literal data. See problems(...) for more details. 

一个 dplyr 解决方案 mutate_all 和管道

说您有以下内容:

> dft
Source: local data frame [11 x 5]

   Bureau.Name Account.Code   X2014   X2015   X2016
1       Senate          110 158,000 211,000 186,000
2       Senate          115       0       0       0
3       Senate          123  15,000  71,000  21,000
4       Senate          126   6,000  14,000   8,000
5       Senate          127 110,000 234,000 134,000
6       Senate          128 120,000 159,000 134,000
7       Senate          129       0       0       0
8       Senate          130 368,000 465,000 441,000
9       Senate          132       0       0       0
10      Senate          140       0       0       0
11      Senate          140       0       0       0

并希望删除一年变量X2014-X2016的逗号,并将其转换为数字。另外,假设X2014-X2016被读入为因素(默认)

dft %>%
    mutate_all(funs(as.character(.)), X2014:X2016) %>%
    mutate_all(funs(gsub(",", "", .)), X2014:X2016) %>%
    mutate_all(funs(as.numeric(.)), X2014:X2016)

mutate_all 在内部应用功能 funs 到指定的列

我依次执行一次,一次一个函数(如果您在内部使用多个功能 funs 然后,您可以创建其他不必要的列)

R中的“预处理”:

lines <- "www, rrr, 1,234, ttt \n rrr,zzz, 1,234,567,987, rrr"

可以使用 readLinestextConnection. 。然后仅删除数字之间的逗号:

gsub("([0-9]+)\\,([0-9])", "\\1\\2", lines)

## [1] "www, rrr, 1234, ttt \n rrr,zzz, 1234567987, rrr"

知道但与这个问题无直接相关的ALS是有用的,即可以通过read.csv2(自动化)或read.table(带有“ DEC'-Parameter的设置)来处理逗号作为小数分离器。

编辑:后来,我通过设计新课程发现了如何使用Colclasses。看:

如何将DF加载为R中的1000个分离器作为数字类?

如果数字被“”分开。和小数为“”(1.200.000,00) gsub 你必须 set fixed=TRUE as.numeric(gsub(".","",y,fixed=TRUE))

我认为预处理是必经之路。您可以使用 记事本++ 具有正则表达式替换选项。

例如,如果您的文件是这样的:

"1,234","123","1,234"
"234","123","1,234"
123,456,789

然后,您可以使用正则表达式 "([0-9]+),([0-9]+)" 并用 \1\2

1234,"123",1234
"234","123",1234
123,456,789

那你可以使用 x <- read.csv(file="x.csv",header=FALSE) 读取文件。

一种非常方便的方法是 readr::read_delim-家庭。从这里举一个例子: 将CSV与多个分离器导入r 您可以按照以下方式进行操作:

txt <- 'OBJECTID,District_N,ZONE_CODE,COUNT,AREA,SUM
1,Bagamoyo,1,"136,227","8,514,187,500.000000000000000","352,678.813105723350000"
2,Bariadi,2,"88,350","5,521,875,000.000000000000000","526,307.288878142830000"
3,Chunya,3,"483,059","30,191,187,500.000000000000000","352,444.699742995200000"'

require(readr)
read_csv(txt) # = read_delim(txt, delim = ",")

这导致了预期的结果:

# A tibble: 3 × 6
  OBJECTID District_N ZONE_CODE  COUNT        AREA      SUM
     <int>      <chr>     <int>  <dbl>       <dbl>    <dbl>
1        1   Bagamoyo         1 136227  8514187500 352678.8
2        2    Bariadi         2  88350  5521875000 526307.3
3        3     Chunya         3 483059 30191187500 352444.7

使用read_delim函数,这是 readr 库,您可以指定其他参数:

locale = locale(decimal_mark = ",")

read_delim("filetoread.csv", ';", locale = locale(decimal_mark = ","))

*Semicolon在第二行意味着READ_DELIM将读取CSV分离值。

这将有助于读取以逗号作为适当数字的所有数字。

问候

Mateusz Kania

我们也可以使用 readr::parse_number, ,列必须是字符。如果我们想将其应用于多列,我们可以使用 lapply

df[2:3] <- lapply(df[2:3], readr::parse_number)
df

#  a        b        c
#1 a    12234       12
#2 b      123  1234123
#3 c     1234     1234
#4 d 13456234    15342
#5 e    12312 12334512

或使用 mutate_atdplyr 将其应用于特定变量。

library(dplyr)
df %>% mutate_at(2:3, readr::parse_number)
#Or
df %>% mutate_at(vars(b:c), readr::parse_number)

数据

df <- data.frame(a = letters[1:5], 
                 b = c("12,234", "123", "1,234", "13,456,234", "123,12"),
                 c = c("12", "1,234,123","1234", "15,342", "123,345,12"), 
                 stringsAsFactors = FALSE)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top