निश्चित चौड़ाई पाठ फ़ाइल पढ़ें


90

मैं अपने आर सत्र में इस बदसूरत-स्वरूपित डेटा-लोड को लोड करने की कोशिश कर रहा हूं: http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for

Weekly SST data starts week centered on 3Jan1990

Nino1+2      Nino3        Nino34        Nino4
Week          SST SSTA     SST SSTA     SST SSTA     SST SSTA 
03JAN1990     23.4-0.4     25.1-0.3     26.6 0.0     28.6 0.3 
10JAN1990     23.4-0.8     25.2-0.3     26.6 0.1     28.6 0.3 
17JAN1990     24.2-0.3     25.3-0.3     26.5-0.1     28.6 0.3

अब तक, मैं लाइनों के साथ पढ़ सकते हैं

  x = readLines(path)

लेकिन फ़ाइल 'व्हाइट स्पेस' को '-' को सेपरेटर के रूप में मिलाती है, और मैं रेगेक्स विशेषज्ञ नहीं हूं। मैं इसे एक अच्छे और साफ R डेटा-फ्रेम में बदलने पर किसी भी मदद की सराहना करता हूं। धन्यवाद!


5
और read.fwfनिश्चित चौड़ाई वाले स्वरूपित डेटा को पढ़ने के लिए एक नज़र डालें ।
पॉल हेमस्ट्रा

1
मुझे लगता है कि प्रत्येक पंक्ति को संसाधित करना बेहतर विचार है। यह '-' को '' वर्णों के साथ मिलाता है।
फर्नांडो

वैकल्पिक रूप से, आप कह सकते हैं कि श्वेत-स्थान या - केवल एक वर्ण है, इसलिए पहले एक स्थान की सभी एकाधिक घटनाओं को एक टैब वर्ण के साथ बदलें, फिर सभी टैब-अलग प्रविष्टि के ऑन - या श्वेत स्थान को विभाजित करें।
गीतालीलाब

निश्चित चौड़ाई = कोई विभाजक नहीं। इसका मतलब है कि "-" एक ऋण चिह्न है और रिक्तियां विभाजक भी नहीं हैं, वे बस तब होती हैं जब संख्या पूरी उपलब्ध चौड़ाई को नहीं भरती है
Eusebio Rufian-Zilbermann

जवाबों:


183

यह एक निश्चित चौड़ाई की फ़ाइल है। read.fwf()इसे पढ़ने के लिए उपयोग करें :

x <- read.fwf(
  file=url("http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for"),
  skip=4,
  widths=c(12, 7, 4, 9, 4, 9, 4, 9, 4))

head(x)

            V1   V2   V3   V4   V5   V6   V7   V8  V9
1  03JAN1990   23.4 -0.4 25.1 -0.3 26.6  0.0 28.6 0.3
2  10JAN1990   23.4 -0.8 25.2 -0.3 26.6  0.1 28.6 0.3
3  17JAN1990   24.2 -0.3 25.3 -0.3 26.5 -0.1 28.6 0.3
4  24JAN1990   24.4 -0.5 25.5 -0.4 26.5 -0.1 28.4 0.2
5  31JAN1990   25.1 -0.2 25.8 -0.2 26.7  0.1 28.4 0.2
6  07FEB1990   25.8  0.2 26.1 -0.1 26.8  0.1 28.4 0.3

अपडेट करें

पैकेज readr(अप्रैल, 2015 को जारी) एक सरल और तेज विकल्प प्रदान करता है।

library(readr)

x <- read_fwf(
  file="http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for",   
  skip=4,
  fwf_widths(c(12, 7, 4, 9, 4, 9, 4, 9, 4)))

गति तुलना: readr::read_fwf()~ 2x से अधिक तेज थी utils::read.fwf ()


8
@ और आपको कैसे पता चला कि चौड़ाई और स्किप क्या थे?
कोबा

12
@ कोबा: मैंने एक टेक्स्ट एडिटर में उन पंक्तियों को कॉपी और पेस्ट किया है जिसमें एक कॉलम काउंट था और मैंने मैन्युअल रूप से प्रत्येक कॉलम के लिए चौड़ाई (जब आवश्यक हो, व्हाट्सएप सहित) गिना। इसके अलावा आप बता सकते हैं कि कच्चे डेटा पर जाने से पहले आपको 4 पूरी लाइनों को छोड़ना होगा।
रेय्यरेंग

5
@ अवांछित व्हाट्सएप को छोड़ने के लिए नकारात्मक स्तंभ चौड़ाई के साथ नीचे पवित्रा का उत्तर स्वीकृत उत्तर के लिए बेहतर अनुकूल हो सकता है।
मैरियस बुटिक 19

1
@Andrie आपको fwf_widths मान कैसे मिला?
BICube

3
@ मुझे विश्वास readr::fwf_emptyहै कि आप के लिए चौड़ाई का अनुमान लगाने का प्रयास करेंगे। के लिए उदाहरण के लिए readr::read_fwfउपयोग दिखाता है readr::fwf_empty
जेक फिशर

55

चौड़ाई निर्धारित करने का दूसरा तरीका ...

df <- read.fwf(
  file=url("http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for"),
  widths=c(-1, 9, -5, 4, 4, -5, 4, 4, -5, 4, 4, -5, 4, 4),
  skip=4
)

चौड़ाई तर्क में -1 का कहना है कि एक-वर्ण स्तंभ है जिसे अनदेखा किया जाना चाहिए, चौड़ाई तर्क में -5 का कहना है कि पाँच-वर्ण स्तंभ है जिसे अनदेखा किया जाना चाहिए, इसी तरह ...

रेफरी: https://www.inkling.com/read/r-cookbook-paul-teetor-1st/chapter-4/recipe-4-6


20

सबसे पहले, यह सवाल लीक्स द्वारा एक कौरसेरा "गेट डेटा एंड क्लीन इट" कोर्स से है। जबकि सवाल का एक और हिस्सा है, कठिन हिस्सा फ़ाइल को पढ़ रहा है।

उस ने कहा, पाठ्यक्रम ज्यादातर सीखने के लिए है।

मुझे R की निश्चित चौड़ाई प्रक्रिया से नफरत है। यह धीमा है और बड़ी संख्या में चर के लिए, यह बहुत जल्दी कुछ स्तंभों को नकारने के लिए दर्द बन जाता है, आदि।

मुझे लगता है कि इसका उपयोग करना आसान है readLines()और फिर उस उपयोग substr()से अपने चर बनाने के लिए

x <- readLines(con=url("http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for"))

# Skip 4 lines
x <- x[-(1:4)]

mydata <- data.frame(var1 = substr(x, 1, 10),
                     var2 = substr(x, 16, 19),
                     var3 = substr(x, 20, 23),
                     var4 = substr(x, 29, 32)  # and so on and so on
                     )

2
इस दृष्टिकोण ने मेरे लिए काम किया। दो अतिरिक्त सुझाव: 1) आप mydata को केवल आपके द्वारा आवश्यक डेटा होने के लिए परिभाषित कर सकते हैं। तो यह उतना ही सरल हो सकता है, जितना mydata <- data.frame(var4 = substr(x,29,32))कि आपको केवल चौथे कॉलम डेटा की जरूरत है। इसके अलावा, विंडोज उपयोगकर्ताओं के लिए, टेक्स्टएफ़एक्स प्लगइन के साथ नोटपैड ++ आपको एक सरल और सरल, गिने हुए चरित्र शासक मिलेगा ताकि आप यह पता लगा सकें कि शुरू में क्या रखा जाए और मूल्यों को रोक दिया जाए substr। ध्यान दें, हालांकि स्टॉप वैल्यू आपके द्वारा संरक्षित किए जाने वाले अंतिम चरित्र की स्थिति से एक अधिक है।
GlobalSchmidt

13

अब आप read_fwf()Hadley Wickham के readrपैकेज में फ़ंक्शन का उपयोग कर सकते हैं ।

आधार की तुलना में एक विशाल प्रदर्शन में सुधार की उम्मीद की जानी है read.fwf()


5

मैं यहाँ R में फिक्स्ड-चौड़ाई फ़ाइलों को पढ़ने के लिए विकल्पों की सूची प्रस्तुत करता हूं , साथ ही कुछ बेंचमार्क प्रदान करता हूं जिसके लिए सबसे तेज़ है।

मेरे पसंदीदा दृष्टिकोण के freadसाथ गठबंधन करना है stringi; यह सबसे तेज़ दृष्टिकोण के रूप में प्रतिस्पर्धी है, और इसमें आपके डेटा को संग्रहीत करने का अतिरिक्त लाभ (IMO) है data.table:

library(data.table)
library(stringi)

col_ends <- 
  list(beg = c(1, 10, 15, 19, 23, 28, 32, 36,
               41, 45, 49, 54, 58),
       end = c(9, 14, 18, 22, 27, 31, 35,
               40, 44, 48, 53, 57, 61))

data = fread(
  "http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for", 
  header = FALSE, skip = 4L, sep = NULL
  )[, lapply(1:(length(col_ends$beg)),
             function(ii) 
               stri_sub(V1, col_ends$beg[ii], col_ends$end[ii]))
    ][ , paste0("V", c(2, 5, 8, 11)) := NULL]
#              V1   V3   V4   V6   V7   V9  V10  V12  V13
#    1: 03JAN1990 23.4 -0.4 25.1 -0.3 26.6  0.0 28.6  0.3
#    2: 10JAN1990 23.4 -0.8 25.2 -0.3 26.6  0.1 28.6  0.3
#    3: 17JAN1990 24.2 -0.3 25.3 -0.3 26.5 -0.1 28.6  0.3
#    4: 24JAN1990 24.4 -0.5 25.5 -0.4 26.5 -0.1 28.4  0.2
#    5: 31JAN1990 25.1 -0.2 25.8 -0.2 26.7  0.1 28.4  0.2
#   ---                                                  
# 1365: 24FEB2016 27.1  0.9 28.4  1.8 29.0  2.1 29.5  1.4
# 1366: 02MAR2016 27.3  1.0 28.6  1.8 28.9  1.9 29.5  1.4
# 1367: 09MAR2016 27.7  1.2 28.6  1.6 28.9  1.8 29.6  1.5
# 1368: 16MAR2016 27.5  1.0 28.8  1.7 28.9  1.7 29.6  1.4
# 1369: 23MAR2016 27.2  0.9 28.6  1.4 28.8  1.5 29.5  1.2

ध्यान दें कि freadव्हाट्सएप को स्वचालित रूप से लीडिंग और ट्रेलिंग स्ट्रिप्स - कभी-कभी, यह अवांछनीय है, जिस स्थिति में सेट किया गया है strip.white = FALSE


हम कॉलम चौड़ाई के वेक्टर के साथ शुरुआत भी wwकर सकते थे:

ww <- c(9, 5, 4, 4, 5, 4, 4, 5, 4, 4, 5, 4, 4)
nd <- cumsum(ww)

col_ends <-
  list(beg = c(1, nd[-length(nd)]+1L),
       end = nd)

और हम नकारात्मक सूचकांकों का उपयोग करके अधिक मजबूत तरीके से बाहर करने के लिए कौन से कॉलम उठा सकते हैं:

col_ends <- 
  list(beg = c(1, -10, 15, 19, -23, 28, 32, -36,
               41, 45, -49, 54, 58),
       end = c(9, 14, 18, 22, 27, 31, 35,
               40, 44, 48, 53, 57, 61))

फिर के col_ends$beg[ii]साथ abs(col_ends$beg[ii])और अगली पंक्ति में बदलें :

paste0("V", which(col_ends$beg < 0))

अंत में, यदि आप चाहते हैं कि कॉलम के नाम प्रोग्राम के अनुसार भी पढ़े जा सकें, तो आप साफ कर सकते हैं readLines:

cols <-
  gsub("\\s", "", 
       sapply(1:(length(col_ends$beg)),
              function(ii) 
                stri_sub(readLines(URL, n = 4L)[4L], 
                         col_ends$beg[ii]+1L,
                         col_ends$end[ii]+1L)))

cols <- cols[cols != ""]

(ध्यान दें कि freadहेडर पंक्ति को हटाने के लिए इस चरण के संयोजन को तालिका की एक प्रति बनाने की आवश्यकता होगी, और इस प्रकार बड़े डेटा सेट के लिए अक्षम होगा)


4

मैं आर के बारे में एक बात नहीं जानता, लेकिन मैं आपको एक रेगेक्स प्रदान कर सकता हूं जो इस तरह की रेखाओं से मेल खाएगा:

\s[0-9]{2}[A-Z]{3}[0-9]{4}(\s{5}[0-9]+\.[0-9]+[ -][0-9]+\.[0-9]+){4}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.