2015-02-05 5 views
5

मुझे कई सीएसवी फाइलें मिलती हैं (और भविष्य में प्राप्त होंगी) अर्धविराम का उपयोग डेलीमीटर और अल्पविराम के रूप में अल्पविराम के रूप में करते हैं। अब तक मुझे यह पता नहीं लगाया जा सकता है कि इन फ़ाइलों को प्रो आयात का उपयोग करके एसएएस में कैसे आयात किया जाए - या किसी अन्य स्वचालित फैशन में मैन्युअल रूप से परिवर्तनीय नामों के साथ गड़बड़ करने की आवश्यकता के बिना।सीएसवी फ़ाइल को डिलीमीटर के साथ ";" के रूप में कैसे आयात करें और एसएएस में दशमलव विभाजक "," के रूप में?

नमूना डेटा बनाएं:

%let filename = %sysfunc(pathname(work))\sap.csv; 

data _null_; 
    file "&filename"; 
    put 'a;b'; 
    put '12345,11;67890,66'; 
run; 

आयात कोड:

proc import out = sap01 
datafile= "&filename" 
dbms = dlm; 
delimiter = ";"; 
GETNAMES = YES; 
run; 

आयात जैसे 350,58 चर "राशि" के लिए एक मूल्य (जिसमें 350.58 से मेल खाती है के बाद यूएस प्रारूप) एसएएस में 35,058 (जिसका अर्थ है थर्डफिथसैंड ...) जैसा दिखता है (और जर्मन एक्सेल में पुनः निर्यात के बाद यह 35.058,00 जैसा दिखता है)।

data sap02; set sap01; 
AMOUNT = AMOUNT/100; 
format AMOUNT best15.2; 
run; 

मुझे आश्चर्य है कि सीवीएस-आयात के लिए दशमलव विभाजक (सीमांकक के विनिर्देश के समान) को परिभाषित करने का आसान तरीका है तो: एक सरल लेकिन गंदा वैकल्पिक हल निम्नलिखित होगा। .. या मेरे कामकाज की तुलना में कोई अन्य "क्लीनर" समाधान। अग्रिम में बहुत धन्यवाद!

+0

35.358,00, यह एक स्ट्रिंग चर की तरह लग रहा
substitute_commasep.perl पर्ल कार्यक्रम

पर्ल कोड का नाम है। क्या यह 35,058,00 है? –

+0

धन्यवाद, मैंने अपनी पोस्ट संपादित की है! – Joz

उत्तर

5

तकनीकी रूप से dbms=dlmdbms=csv का उपयोग नहीं करना चाहिए, हालांकि यह चीजों को समझता है। सीएसवी का अर्थ है "अल्पविराम से अलग मूल्य", जबकि डीएलएम का मतलब है "सीमित", जो यहां सही है।

मुझे नहीं लगता कि एसएएस को PROC IMPORT के माध्यम से अल्पविराम के साथ पढ़ाने का सीधा तरीका है। डेटा में पढ़ने के दौरान आपको NUMXw.d सूचना का उपयोग करने के लिए एसएएस को बताना होगा, और मुझे एसएएस में उस सेटिंग को मजबूर करने का कोई तरीका नहीं दिख रहा है। (एक अल्पविराम, NLDECSEPARATOR साथ उत्पादन के लिए एक विकल्प नहीं है, लेकिन मुझे नहीं लगता कि यहां काम करता है।)

आपका सबसे अच्छा शर्त या तो PROC IMPORT चलाने के लिए डेटा कदम कोड अपने आप को लिखने के लिए, या है, के लिए जाना लॉग इन करें, और अपने प्रोग्राम में कोड में पढ़ने/कॉपी पेस्ट करें; तो प्रत्येक रीड-इन रिकॉर्ड के लिए :NUMX10. जोड़ें या जो भी फ़ील्ड की उचित अधिकतम चौड़ाई है। यह कुछ इस तरह दिख रहा है:

data want; 
    infile "whatever.txt" dlm=';' lrecl=32767 missover; 
    input 
    firstnumvar :NUMX10. 
    secondnumvar :NUMX10. 
    thirdnumvar :NUMX10. 
    fourthnumvar :NUMX10. 
    charvar :$15. 
    charvar2 :$15. 
    ; 
run; 

यह बहुत सारी जानकारी और प्रारूप कोड भी उत्पन्न करेगा; आप रीड-इन में सूचना को जोड़ने के बजाय BEST. के बजाय सूचनाओं को वैकल्पिक रूप से NUMX10. में परिवर्तित कर सकते हैं। जब तक आपके पास डेट फ़ील्ड न हो, आप केवल सूचनाएं हटा सकते हैं।

data want; 
    infile "whatever.txt" dlm=';' lrecl=32767 missover; 
    informat firstnumvar secondnumvar thirdnumvar fourthnumvar NUMX10.; 
    informat charvar $15.; 
    format firstnumvar secondnumvar thirdnumvar fourthnumvar BEST12.; 
    format charvar $15.; 
    input 
    firstnumvar 
    secondnumvar 
    thirdnumvar 
    fourthnumvar 
    charvar $ 
    ; 
run; 
+0

आपकी मदद के लिए धन्यवाद, जो! मैंने अभी अपनी पोस्ट को डीबीएमएस विकल्प wrt संपादित किया है। आपके अन्य विचार काफी रोचक हैं लेकिन अभी भी कामकाज की तरह हैं। यह विश्वास करना मुश्किल है कि एसएएस इस तरह की एक बड़ी समस्या को संभाल नहीं सकता है। लेकिन मुझे डर है कि आप सही हो सकते हैं ... – Joz

+0

एसएएस इसे संभाल सकता है और जो आपको दिखाता है कि कैसे। प्रोसी आयात मूलभूत फाइलों में पढ़ने के लिए उपयोगिता के अलावा कुछ भी नहीं है - यह फ़ाइल को पढ़ने के लिए डेटा चरण लिखता है। अगर फ़ाइल "मूल" के अपने विचार के अनुरूप नहीं है तो आपको डेटा चरण लिखना होगा। – DomPazz

+0

संपादित करें: यह मानना ​​मुश्किल है कि एसएएस एक स्वचालित फैशन में ऐसी एक बड़ी समस्या को संभाल नहीं सकता है। लेकिन मैं वर्तमान में जो के समाधान के साथ काम कर रहा हूं, बहुत बहुत धन्यवाद! – Joz

0

आपका सबसे अच्छा शर्त है या तो डेटा कदम कोड लिखने के लिए अपने आप को, या PROC आयात चलाने के लिए, लॉग पर जाएँ, और कॉपी/ अपने कार्यक्रम में कोड में पढ़ने को चिपकाने के लिए

इसमें कोई कमी है। यदि सीएसवी फ़ाइल के स्टैक्चर में कोई बदलाव है, उदाहरण के लिए एक परिवर्तित कॉलम ऑर्डर, तो किसी को एसएएस प्रोग्राम में कोड बदलना होगा।
तो इनपुट को बदलने के लिए सुरक्षित है, संख्यात्मक क्षेत्रों में कॉमा को डॉट के साथ प्रतिस्थापित करना और संशोधित इनपुट एसएएस पास करना सुरक्षित है।

पहला विचार इस के लिए एक पर्ल प्रोग्राम का उपयोग करना था, और उसके बाद संशोधित इनपुट को पढ़ने के लिए एसएएस में एक पाइप के साथ एक फ़ाइल नाम का उपयोग करना था।
दुर्भाग्यवश proc आयात में एक एसएएस प्रतिबंध है: आयात प्रक्रिया डिस्क के अलावा FILENAME कथन के लिए डिवाइस प्रकार या एक्सेस विधियों का समर्थन नहीं करती है।
इसलिए किसी को समायोजित इनपुट के साथ डिस्क पर वर्कफ़ाइल बनाना है।

मैंने सीएसवी फ़ाइल पढ़ने के लिए सीवीएस_PP पैकेज का उपयोग किया।
testdata.csv में पढ़ने के लिए सीएसवी डेटा शामिल है।

# use lib "/........"; # specifiy, if Text::CSV_PP is locally installed. Otherwise error message: Can't locate Text/CSV_PP.pm in ....; 
use Text::CSV_PP; 
use strict; 
    my $csv = Text::CSV_PP->new({ binary => 1 
           ,sep_char => ';' 
          }) or die "Error creating CSV object: ".Text::CSV_PP->error_diag(); 
    open my $fhi, "<", "$ARGV[0]" or die "Error reading CSV file: $!"; 
    while (my $colref = $csv->getline($fhi)) { 
     foreach (@$colref) {    # analyze each column value 
     s/,/\./ if /^\s*[\d,]*\s*$/; # substitute, if the field contains only numbers and , 
     } 
     $csv->print(\*STDOUT, $colref); 
     print "\n"; 
    } 
    $csv->eof or $csv->error_diag(); 
    close $fhi; 

एसएएस कोड:

filename readcsv pipe "perl substitute_commasep.perl testdata.csv"; 
filename dummy "dummy.csv"; 
data _null_; 
    infile readcsv; 
    file dummy; 
    input; 
    put _infile_; 
run; 
proc import datafile=dummy 
    out=data1 
    dbms=dlm 
    replace; 
    delimiter=';'; 
    getnames=yes; 
    guessingrows=32767; 
run; 
संबंधित मुद्दे

 संबंधित मुद्दे