जब कुछ संख्याओं में हजार विभाजक के रूप में अल्पविराम होते हैं तो डेटा कैसे पढ़ें?


117

मेरे पास एक csv फ़ाइल है जहां कुछ संख्यात्मक मानों को कॉमा के साथ हजार विभाजक के रूप में व्यक्त किया जाता है, उदाहरण "1,513"के लिए 1513। R में डेटा को पढ़ने का सबसे सरल तरीका क्या है?

मैं उपयोग कर सकता हूं read.csv(..., colClasses="character"), लेकिन फिर मुझे उन स्तंभों को संख्यात्मक में परिवर्तित करने से पहले संबंधित तत्वों से कॉमा को बाहर निकालना होगा, और मुझे ऐसा करने का एक साफ तरीका नहीं मिल सकता है।

जवाबों:


141

सुनिश्चित नहीं हैं कि कैसे के बारे में है करने के लिए read.csvयह ठीक से व्याख्या है, लेकिन आप उपयोग कर सकते हैं gsubबदलने के लिए ","के साथ "", और उसके बाद करने के लिए स्ट्रिंग में कनवर्ट numericका उपयोग कर as.numeric:

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

यह पहले भी आर-हेल्प (और यहां Q2 में ) पर जवाब दिया गया था ।

वैकल्पिक रूप से, आप फ़ाइल को प्री-प्रोसेस कर सकते हैं, उदाहरण के लिए sedयूनिक्स में।


60

आप अपने लिए अर्ध-स्वचालित रूप से read.table या read.csv कर सकते हैं। पहले एक नई कक्षा की परिभाषा बनाएं, फिर एक रूपांतरण फ़ंक्शन बनाएँ और इसे सेटर्स फ़ंक्शन का उपयोग करके "के रूप में" विधि के रूप में सेट करें:

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'))

3
यह बहुत अच्छी ट्रिक है। इसका उपयोग आयात-रूपांतरण के लिए किया जा सकता है (उदाहरण के लिए वाई / एन मान को तार्किक वेक्टर का उपयोग करके परिवर्तित करना setAs("character", "logical.Y.N", function(from) c(Y=TRUE,N=FALSE)[from] ))।
मारेक

1
इसी तरह की समस्या में एक ही चाल का उपयोग करें । और जोड़ने के लिए: एक setClass("num.with.commas")या तो उपयोग कर सकता है या suppresMessage(setAs(.....))लापता वर्ग के बारे में संदेश से बचने के लिए।
मारेक

हाय ग्रेग, इस काम को साझा करने के लिए धन्यवाद। निष्पादन के बाद मुझे निम्नलिखित चेतावनी मिल रही है: हस्ताक्षर '' चरित्र '', '' num.with.commas '' के साथ 'सामंजस्य' के लिए विधि: वर्ग "num.with.commas" के लिए कोई परिभाषा नहीं है। किसी भी विचार यह है कि समस्या यहाँ क्या है, मेरे पास शब्द के लिए आपका कोड शब्द है?
TheGoat

मैंने इसी तरह की समस्या लिंक की जाँच की और देखा कि मुझे कक्षा सेट करने की आवश्यकता है! साफ सुथरी चाल के लिए धन्यवाद।
TheGoat

17

मैं डेटा को पूर्व-संसाधित करने के बजाय R का उपयोग करना चाहता हूं क्योंकि यह डेटा को संशोधित करते समय इसे आसान बनाता है। शेन के उपयोग के सुझाव के बाद gsub, मुझे लगता है कि यह मेरे बारे में जितना साफ हो सकता है:

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

क्या ColClasses = "char" सभी कॉलम को चार होने के लिए बाध्य नहीं करता है, जिसमें 15:41 के अलावा अन्य भी char होते हैं? हो सकता है कि read.csv () तय करें और फिर उन 15:41 को कॉलिंग में परिवर्तित करें जिससे आपको 'अधिक' संख्यात्मक कॉलम मिल सकें।
डर्क एडल्डबेल्टेल

हां, लेकिन जैसा कि मेरे प्रश्न में उल्लेख किया गया है, अन्य सभी कॉलम चरित्र हैं। मैं इसके बजाय as.is = TRUE का उपयोग कर सकता हूं जो अधिक सामान्य होगा। लेकिन read.csv () को डिफॉल्ट तर्कों का उपयोग करके तय करना मददगार नहीं है क्योंकि यह किसी भी चीज को एक कारक की तरह दिखने वाले कारक में बदल देगा, जो संख्यात्मक कॉलम के लिए परेशानी का कारण बनता है क्योंकि तब वे as.numeric () का उपयोग करके ठीक से परिवर्तित नहीं होते हैं ।
रोब हंडमैन

आपको पढ़ने की तालिका में डिक = तर्क को "" पर सेट करने पर विचार करना चाहिए। यह read.csv2 के लिए डिफ़ॉल्ट है, लेकिन comma read.csv () में हार्डवेअर है।
IRTFM

15

यह सवाल कई साल पुराना है, लेकिन मैं इस पर अड़ गया, जिसका मतलब है कि शायद दूसरे लोग भी करेंगे।

readrपुस्तकालय / पैकेज इसे करने के लिए कुछ अच्छा विशेषताएं है। उनमें से एक "गड़बड़" कॉलम की व्याख्या करने का एक अच्छा तरीका है, इन जैसे।

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

यह प्रदान करता है

स्रोत: स्थानीय डेटा फ्रेम [४ x १]

  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. 

7

एक 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_allfunsनिर्दिष्ट कॉलम के अंदर फ़ंक्शन (ओं) को लागू करता है

मैंने इसे क्रमिक रूप से किया था, एक समय में एक फ़ंक्शन (यदि आप अंदर कई फ़ंक्शन का उपयोग करते हैं funsतो आप अतिरिक्त, अनावश्यक कॉलम बनाते हैं)


3
mutate_eachपदावनत किया गया है। क्या आप अपने उत्तर को mutate_atया इसी तरह से अपडेट करना चाहते हैं ?
T_T

6

आर में "प्रीप्रोसेस":

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

उपयोग कर सकते हैं readLinesएक पर textConnection। फिर केवल उन अल्पविरामों को हटाएं जो अंकों के बीच हैं:

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

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

यह जानना उपयोगी है, लेकिन इस सवाल के लिए सीधे प्रासंगिक नहीं है कि दशमलव विभाजकों के रूप में अल्पविराम को read.csv2 (स्वचालित रूप से) या read.table ('dec'-पैरामीटर की सेटिंग के साथ) द्वारा नियंत्रित किया जा सकता है।

संपादित करें: बाद में मुझे पता चला कि एक नए वर्ग को डिज़ाइन करके कोलक्लासेस का उपयोग कैसे किया जाता है। देख:

संख्यात्मक वर्ग के रूप में R में 1000 विभाजक के साथ df कैसे लोड करें?


धन्यवाद, यह एक अच्छा पॉइंटर था, लेकिन यह उन अंकों के लिए काम नहीं करता है, जिनमें कई दशमलव चिह्न होते हैं, जैसे 1,234,567.89 - इस समस्या के चारों ओर काम करने के लिए आर में एक Google स्प्रेडशीट आयात करने के लिए आवश्यक है, देखें stackoverflow.com/a/30020171/3096626 एक साधारण के लिए फ़ंक्शन जो कई दशमलव के लिए काम करता है
फ्लेक्सपोसिव

4

यदि संख्या "से अलग हो जाती है।" और gsubआपको कॉल करने में "," (1.200.000,00) तक की कमी आती हैset fixed=TRUE as.numeric(gsub(".","",y,fixed=TRUE))


3

एक बहुत ही सुविधाजनक तरीका readr::read_delim-family है। यहाँ से उदाहरण लेते हुए: आर में कई विभाजकों के साथ सीएसवी आयात करना आप इसे निम्नानुसार कर सकते हैं:

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

3

Read_delim फ़ंक्शन का उपयोग करना, जो रीड लाइब्रेरी का हिस्सा है , आप अतिरिक्त पैरामीटर निर्दिष्ट कर सकते हैं:

locale = locale(decimal_mark = ",")

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

* दूसरी पंक्ति में अर्धविराम का अर्थ है कि read_delim csv अर्धविराम से अलग किए गए मानों को पढ़ेगा।

यह उचित संख्या के रूप में अल्पविराम के साथ सभी नंबरों को पढ़ने में मदद करेगा।

सादर

माटूस कानिया


3

हम भी उपयोग कर सकते हैं 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_atसे 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)

1

मुझे लगता है कि प्रीप्रोसेसिंग जाने का रास्ता है। आप नोटपैड ++ का उपयोग कर सकते हैं जिसमें एक नियमित अभिव्यक्ति प्रतिस्थापित विकल्प है।

उदाहरण के लिए, यदि आपकी फ़ाइल इस प्रकार थी:

"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)फ़ाइल को पढ़ने के लिए उपयोग कर सकते हैं ।


22
कुछ भी आप स्क्रिप्ट कर सकते हैं, आपको करना चाहिए। इसे हाथ से करने से त्रुटि का अवसर मिलता है, साथ ही साथ बहुत प्रतिलिपि प्रस्तुत करने योग्य भी नहीं होता है।
हैडले
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.