programing tip

일부 숫자에 천 단위 구분 기호로 쉼표가 포함 된 경우 데이터를 읽는 방법은 무엇입니까?

itbloger 2020. 7. 25. 10:39
반응형

일부 숫자에 천 단위 구분 기호로 쉼표가 포함 된 경우 데이터를 읽는 방법은 무엇입니까?


csv 파일이 있는데 숫자 값 중 일부가 쉼표가있는 1000 구분 기호로 문자열로 표시됩니다 (예 : "1,513"대신) 1513. R로 데이터를 읽는 가장 간단한 방법은 무엇입니까?

사용할 수는 read.csv(..., colClasses="character")있지만 해당 열을 숫자로 변환하기 전에 관련 요소에서 쉼표를 제거해야하며 깔끔한 방법을 찾을 수 없습니다.


확실하지에 대해 어떻게해야하는 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유닉스에서 와 같이 파일을 사전 처리 할 수 ​​있습니다 .


read.table 또는 read.csv가 반자동으로이 변환을 수행하도록 할 수 있습니다. 먼저 새 클래스 정의를 작성한 다음 변환 함수를 작성하고 다음과 같이 setAs 함수를 사용하여 "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'))

데이터를 수정할 때 더 쉽게 데이터를 사전 처리하는 대신 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))})

이 질문은 몇 살이지만, 나는 그것을 우연히 발견했습니다.

readr라이브러리 / 패키지는 몇 가지 좋은 기능을 가지고 있습니다. 그중 하나는 "지저분한"열을 해석하는 좋은 방법입니다.

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를 수행하거나 읽는 동안 처리해야합니다 . 사실 이후에 문제를 해결하려고하면 찾기 어려운 위험한 가정이 있습니다. 플랫 파일이 처음부터 그렇게 악한 이유는 무엇입니까?

예를 들어,에 플래그를 지정하지 않은 경우 다음 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

and want to remove commas from the year variables X2014-X2016, and convert them to numeric. also, let's say X2014-X2016 are read in as factors (default)

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

mutate_all applies the function(s) inside funs to the specified columns

I did it sequentially, one function at a time (if you use multiple functions inside funs then you create additional, unnecessary columns)


"Preprocess" in R:

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

Can use readLines on a textConnection. Then remove only the commas that are between digits:

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

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

It's als useful to know but not directly relevant to this question that commas as decimal separators can be handled by read.csv2 (automagically) or read.table(with setting of the 'dec'-parameter).

Edit: Later I discovered how to use colClasses by designing a new class. See:

How to load df with 1000 separator in R as numeric class?


If number is separated by "." and decimals by "," (1.200.000,00) in calling gsub you must set fixed=TRUE as.numeric(gsub(".","",y,fixed=TRUE))


I think preprocessing is the way to go. You could use Notepad++ which has a regular expression replace option.

For example, if your file were like this:

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

Then, you could use the regular expression "([0-9]+),([0-9]+)" and replace it with \1\2

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

Then you could use x <- read.csv(file="x.csv",header=FALSE) to read the file.


A very convenient way is readr::read_delim-family. Taking the example from here: Importing csv with multiple separators into R you can do it as follows:

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 = ",")

Which results in the expected result:

# 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

Using read_delim function, which is part of readr library, you can specify additional parameter:

locale = locale(decimal_mark = ",")

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

* 두 번째 줄의 세미콜론은 read_delim이 csv 세미콜론으로 구분 된 값을 읽음을 의미합니다.

쉼표가있는 모든 숫자를 적절한 숫자로 읽는 데 도움이됩니다.

문안 인사

마테우스 카 니아


우리는 또한 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_atfrom dplyr사용 하여 특정 변수에 적용하십시오.

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)

참고 URL : https://stackoverflow.com/questions/1523126/how-to-read-data-when-some-numbers-contain-commas-as-thousand-separator

반응형