第二章 數據讀取
2.1 SAS讀取的對象(DBMS、PC File、Flat File、Instream Data)
2.2 SAS與數據交互方式(libname、sql、import\export、infile:input、IO函數、dde、saspipe)
2.3 數據的導入
2.3.1利用LIBNAME語句導入數據
2.3.2利用SQL導入數據
2.3.3 IMPORT導入數據
2.3.4 infile導入數據
2.3.5 INPUT 語句
2.3.6 DDE 方法
2.3.7 sas pipe
2.3.8 IO 函數
2.3.9 Import Wizard 使用導入向導
2.1 SAS讀取對象
在做數據分析前需要獲取數據,成功導入外部數據是SAS分析的第一步,也是最基礎且重要的一步。SAS 作為老牌的統計軟件發展至今,已經集成了豐富的數據獲取與管理功能組件。本章我們就SAS如何獲取數據做重點介紹。
SAS可讀取任意格式、任意類型的原始數據,包括變長記錄、二進制文件、無格式的數據,甚至是包含混亂或缺失數據的文件。
SAS可直接訪問某些廠商的文件,如:BMDP、SPSS 和 OSIRIS 文件。對於其他格式的文件,可以使用 SAS/ACCESS,它可以如同訪問 SAS 內部數據一樣訪問外部數據。例如,可以讀取存儲在 Microsoft Excel 電子表格、Microsoft Access 表、dBASE 文件、ORACLE 或其他 DBMS 中的數據
SAS/ACCESS 提供對以下類型數據的訪問:
2-1
說到數據讀取這個問題,我們可以從 SAS 讀取的對象來說 , 當然也可以從讀取的方式來說。從 SAS 讀取的對象來說,我們可以把外部數據文件歸為四類。
(1)數據庫管理系統(DataBase Management System, DBMS)數據文件,市面的DBMS 非常之多,常見的如 DB2、 Sybase、 mySQL、 MS SQL Server、 Oracle、 Teradata 以及 Hadoop 等。
(2)單機文件(PC File),單機文件應是相對 DBMS 數據文件而言的,常見的單機數據文件包括MS Access、 MS Excel、 Lotus、 DBF 以及大家更熟悉的 JMP、 SPSS、Stata、 Paradox 等軟件的數據文件。
(3)平面文件(Flat File),是一種包含沒有相對關系結構的記錄的文件,一個 Flat File 既可以是純文本文件 (Plain Text File),也可以是二進制文件 (Binary File),對於我們而言,最常見的是純文本 TXT 文件和 CSV 文件。
(4)流式數據(Instream Data),即 SAS 程序中 DATA步里 DATALINES(CARDS)語句后的數據行。
2.2 SAS與數據交互方式
從 SAS 讀取的方式有很多種,具體需要結合實際采取適當的方式。(更准確地講,應該是 SAS 和外部數據交互的方式,因為不僅僅讀入,還有導出等其他交互操作)
(1) LIBNAME 語句, LINAME 語句其實是動用了我們前面提到的數據庫引擎來實現 SAS 與其他數據庫文件的互通,這是 SAS 獲取外部數據庫文件最為快速、直接的方式。
(2) SQL 直通設施(SQL Pass-Through Facility),這是直接在 SAS 會話中使用其原生 SQL 語法的方式。
(3) IMPORT 過程,前面的兩種方式都是包含在 SAS/ACCESS 模塊中的, IMPORT過程則是Base SAS與外部數據集溝通的方式,當然我們在利用IMPORT/EXPORT 過程時,如果安裝且擁有 SAS/ACCESS 模塊的權限,能夠支持的數據類型會更豐富。
(4) INFILE INPUT 語句,這是通過 DATA 步編程的方式讀取外部數據或者流式數據。
(5) INPUT DATALINES 語句,這是通過 DATA 步編程的方式讀取流式數據。
(6) DDE 動態數據交換
(7) sas pipe 信息傳輸管道
(8) IO 函數,通過輸入輸出函數打開數據文件,這是一種比較少見的方式
(9)Import Wizard 使用導入向導
在實際工作中,我們的思維模式通常是碰到一種數據,然后思考采用何種方式讀入。因此,這里引用某位筆者將數據類型和讀入方式做一個綜合總結。從需求出發找解決方法,即從數據類型出發,總結可用的讀入方式,並推薦合適的讀入方式。具體見表 2-2 的總結
2-2
2.3數據的導入
在SAS系統中可以通過數據步編程以及界面操作實現數據的輸入輸出,這里介紹一些常用的通過數據步導入數據的方式。
2.3.1 利用LIBNAME語句導入數據
LIBNAME是與SAS庫關聯的庫引用(libref)的名稱。LIBNAME語句定義SAS邏輯庫。
語法
LIBNAME 邏輯庫名<選擇引擎> '(有效的Windows路徑名或設置為有效Windows路徑名的環境變量 )'
<指定為此庫使用擴展服務器內存>, <指定SAS等待鎖定文件可供另一個進程使用的秒數。>;
LIBNAME 邏輯庫名_ALL_ LIST; (在Log窗口列出邏輯庫的屬性)
LIBNAME 邏輯庫名_ALL_ CLEAR;(清除所有與庫標記的聯系)
LIBNAME聲明概述
LIBNAME語句將libref與永久SAS庫相關聯。 它還可用於列出SAS庫的文件屬性。 LIBNAME語句還用於清除libref。
需要注意的是單詞AUX,CON,NUL,PRN,LPT1-LPT9和COM1-COM9是Windows下的保留字。 不要將它們用作librefs。
使用LIST選項,您可以使用LIBNAME語句列出SAS庫的屬性。 以下為LIBNAME語句導致數據庫屬性列表:
示例 1:指定引用 SAS 文件的邏輯庫引用名
假定您希望定義一個 SAS 邏輯庫,該庫引用 Windows 操作環境中某個包含 SAS 數據集的文件夾。然后,您希望創建並打印新的數據集。下面的程序將定義 Sales 邏輯庫,並引用該邏輯庫中的 SAS 文件。
提示: 可以復制這些程序,然后在 SAS 中提交。不過,需要編輯 LIBNAME語句中的目錄,才能引用操作環境中的現有目錄。
/*************************************/
/* 定義邏輯庫 */
/*************************************/
libname sales 'C:\Users\Xx\Desktop';
/*************************************/
/* 從原始數據創建新數據集 */
/*************************************/
data sales.quarter1;
length Department $ 7 Site $ 8;
input Department Site Quarter Sales;
datalines;
Parts Sydney 1 4043.97
Parts Atlanta 1 6225.26
Parts Paris 1 3543.97
Repairs Sydney 1 5592.82
Repairs Atlanta 1 9210.21
Repairs Paris 1 8591.98
Tools Sydney 1 1775.74
Tools Atlanta 1 2424.19
Tools Paris 1 5914.25
;
run;
/*************************************/
/*打印新數據集 */
/*************************************/
proc print data=sales.quarter1;
run;
例 2:指定引用 DBMS 數據的邏輯庫引用名
現在假定您希望打印 Oracle 表和 DB2 表。下面的程序將說明,如何指定帶有相應的 SAS/ACCESS 引擎和選項的 LIBNAME 語句。您為 DBMS 指定邏輯庫引用名之后,可以使用標准的 SAS 兩級名稱將其中的表和視圖作為 SAS 數據集引用。
由於可以在 SAS 程序中定義任意多的邏輯庫引用名,所以您可以在同一個 SAS 程序中處理源自多個 DBMS 的數據。
(
Libname xx 'D:\mydb';
Libname xxx 'D:\mydb'; (兩個庫標識對應一個物理地址)
Libname xxxx ('D:\mydb1' 'D:\mydb2'); (多個物理地址指定一個邏輯庫))
/*************************************/
/* 以Oracle為引擎建立邏輯庫 */
/*************************************/
libname myorlib oracle user=scott password=tiger
path="blunzer:v7" schema=hrdept;
/*************************************/
/* 以DB2為引擎建立邏輯庫 */
/*************************************/
libname mydblib db2
noprompt="user=testuser;
password=testpass;database=testdb";
/*************************************/
/* 打印 Oracle 表 */
/*************************************/
proc print data=myorlib.all_employees;
where state='CA';
run;
/*************************************/
/* 打印 DB2 表 */
/*************************************/
proc print data=mydblib.customers;
where state='CA';
run;
/*************************************/
/*取消關聯一個或多個當前分配的libref。 */
/*************************************/
libname myorlib clear;
libname mydblib clear;
假定您希望在遠程主機上執行某些處理,然后下載 SAS 結果數據集,在本地主機上創建永久數據集,最后在本地主機上打印報表。下例將說明如何將上述所有任務編入一個程序。
/*************************************/
/*准備登錄 */
/*************************************/
options comamid=netbios remote=netpc;
libname lhost 'c:\sales\reg1';
/*************************************/
/* 登錄並下載數據集 */
/*************************************/
signon;
rsubmit;
libname rhost 'd:\dept12';
proc sort data=rhost.master
out=rhost.sales;
where gross > 5000;
by lastname dept;
run;
proc download data=rhost.sales
out=lhost.sales;
run;
endrsubmit;
/*************************************/
/* 在本地會話中打印數據集 */
/*************************************/
proc print data=lhost.sales;
run;
2.3.2利用SQL(SQL Pass-Through Facility)導入數據
SQL傳遞工具使用SAS / ACCESS連接到DBMS並將語句直接發送到DBMS以供執行。 作為SAS / ACCESS LIBNAME語句的替代方法,此工具允許您使用DBMS的SQL語法。 它支持DBMS支持的任何非ANSI標准的SQL。
但是,並非所有SAS / ACCESS接口都支持此功能。 要確定您的環境是否可用,請參閱主機的SAS / ACCESS功能。
以下是您可以使用SQL傳遞工具完成的任務:
· 使用CONNECT和DISCONNECT語句建立和終止與DBMS的連接。
· 使用其EXECUTE語句將動態非查詢,特定於DBMS的SQL語句發送到DBMS。
· 使用PROC SQL SELECT語句的FROM子句中的CONNECTION TO組件直接從DBMS檢索數據。
您可以在PROC SQL查詢中使用SQL傳遞工具語句,也可以將它們存儲在SQL視圖中。 創建SQL視圖時,您在CONNECT語句中指定的任何參數都將與視圖一起存儲。 因此,在SAS程序中使用視圖時,SAS可以建立與DBMS的適當連接。
有關SQL傳遞工具的DBMS特定詳細信息,請參閱SAS幫助文檔中SAS / ACCESS接口的參考部分。
語法
PROC SQL <option(s)>;
CONNECT TO dbms-name <AS alias>
<(<database-connection-arguments> <connect-statement-arguments> )>;
DISCONNECT FROM dbms-name | alias;
EXECUTE (dbms-specific-SQL-statement) BY dbms-name | alias;
SELECT column-list FROM CONNECTION TO dbms-name | alias (dbms-query)
示例1:導入Excel文件
示例2:SAS訪問數據庫
這里說的訪問數據庫不是把數據庫作為一個lib 來訪問,而是通過connection 來訪問,為什么要用sas/access 的這種辦法來訪問DBMS呢,是因為要處理大量數據的時候,SAS 要在本機生成一些文件(臨時文件之類),而把sql 語句直接提交給DBMS,由DMBS 執行,SAS 就不會需要中間這些步驟了。
簡單來說,就是把sql 語句交給DBMS engine 來執行,這種方式在SAS 里叫做
Pass-Through Facility。
下面是一個完整的pass-through 方式執行sql 的語句:
proc sql;
connect to oracle as mydb (Path='ConnectionString' user='dbuser'
password='passwd');
%put &sqlxmsg;
select count(*) from connection to mydb
select count(*) from connection to mydb
(select * from scott);
%put &sqlxmsg;
disconnect from mydb;
quit;
1. connect to 語句是連接到數據庫,然后給sas 一個別名,叫mydb
2. select count(*) from connection to mydb 這里是指從DBMS 返回的結果從select 數據,而真正運行在dbms 端的語句則是括號中的這句(select * from suspect_duplicates_2);
3. 斷開連接: disconnect from mydb;
%put &sqlxmsg; 是sas 的宏,用來輸出dbms 的錯誤信息
以上的示例是用來select 有結果集的,對於沒有結果集的sql 語句,要用到EXECUTE,見下例:
proc sql;
connect to oracle as mydb (Path='ConnectionString' user='dbuser'
password='passwd');
%put &sqlxmsg;
execute
(create table .......) by mydb;
%put &sqlxmsg;
disconnect from mydb;
quit;
括號里的sql 語句可以是create, update, 等等...
PASSTHTOUGH方式通過CONNECT語句建立SAS和其他數據庫之間的通信,並使用SQL過程將其他數據庫數據直接導入到SAS系統
在此示例中,SAS / ACCESS使用dbcon別名連接到Teradata DBMS。
proc sql;
connect to teradata as dbcon (user=testuser pass=testpass);
quit;
示例使用別名DBCON連接oracle(連接別名是可選的):
proc sql;
connect to oracle as bieming
(user=yonghuming password=mima
path=lujing);
quit;
要退出SQL傳遞工具,請使用工具DISCONNECT語句,然后退出PROC SQL語句。 此示例使用別名DBCON1斷開用戶與DB2數據庫的連接,並終止SQL過程。
proc sql;
connect to db2 as dbcon1 (ssid=db2a);
…more SAS statements…
disconnect from dbcon1;
quit;
此示例將Oracle SQL查詢(下面突出顯示)發送到Oracle數據庫進行處理。 Oracle SQL查詢的結果充當PROC SQL FROM子句的虛擬表。 在此示例中,MYCON是連接別名。
proc sql;
connect to oracle as mycon (user=myusr1
password=mypwd1 path='mysrv1');
%put &sqlxmsg;
select *
from connection to mycon
(select empid, lastname, firstname,
hiredate, salary
from employees where
hiredate>='31-DEC-88');
%put &sqlxmsg;
disconnect from mycon;
quit;
CONNECTION TO組件指定要使用或要創建的DBMS連接(如果已省略CONNECT語句)。 然后,CONNECTION TO使您可以直接通過PROC SQL查詢檢索DBMS數據。
您在PROC SQL SELECT語句的FROM子句中使用CONNECTION TO組件:
PROC SQL;
SELECT column-list
FROM CONNECTION TO dbms-name (dbms-query)other optional PROC SQL clauses
QUIT;
此示例為查詢提供名稱並將其存儲為SQL視圖樣本。
libname samples 'SAS-library';
proc sql;
connect to oracle as mycon (user=myusr1
password=mypwd1 path='mysrv1');
%put &sqlxmsg;
create view samples.hires88 as
select *
from connection to mycon
(select empid, lastname, firstname,
hiredate, salary
from employees where
hiredate>='31-DEC-88');
%put &sqlxmsg;
disconnect from mycon;
quit;
2.3.3 IMPORT導入數據
IMPORT程序有什么作用?
IMPORT過程從外部數據源讀取數據並將其寫入SAS數據集。 在Base SAS 9.4中,您可以導入JMP文件和分隔文件。
在分隔文件中,分隔符(例如空格,逗號或制表符)分隔數據值列。 如果您將SAS / ACCESS接口許可給PC文件,則其他外部數據源可以包括Microsoft Access數據庫文件,Microsoft Excel文件和Lotus電子表格。
運行IMPORT過程時,它會讀取輸入文件並將數據寫入指定的SAS數據集。 默認情況下,IMPORT過程期望變量名稱出現在第一行中。 該過程掃描前20行以計算變量,並嘗試確定每個變量的正確信息和格式。 您可以使用IMPORT過程的語句執行以下操作:
· 指示SAS掃描變量以確定類型和長度的行數(GUESSINGROWS =)
· 指示SAS開始讀取數據的行(DATAROW =)
· 修改SAS是否提取變量名稱(GETNAMES =)
默認情況下,IMPORT過程將分隔文件讀取為不同的記錄長度文件。 如果外部文件具有固定長度格式,請使用帶有INFILE語句的SAS DATA步驟,該語句包含RECFM = 和LRECL =選項。
語法:
PROC IMPORT
DATAFILE ="filename"|TABLE ="表名"
OUT = <libref。> SAS數據集<(SAS數據集選項)>
<DBMS = identifier> <REPLACE>;
從分隔文件導入的語句
Datarow= N;
DELIMITER = char |'nn'x;
GETNAMES = YES | NO;
GUESSINGROWS = n |MAX;
PROC IMPORT將外部數據文件導入SAS數據集
DATAROW開始從分隔文本文件中的特定行讀取數據
DELIMITER指定用於分隔輸入文件中數據列的分隔符
GETNAMES從輸入文件第一行的數據值生成SAS變量名
GUESSINGROWS指定要掃描的輸入文件的行數,以確定變量的相應數據類型和長度
可選參數摘要
DBMS=標識符
指定要導入的數據類型。
Replace
覆蓋現有的SAS數據集。
SAS data set options
指定SAS數據集選項。
DATAFILE="filename" | "fileref"
指定輸入PC文件,電子表格或分隔外部文件的完整路徑和文件名或fileref。 fileref是與輸出文件的物理位置相關聯的SAS名稱。 要分配fileref,請使用FILENAME語句
僅當SAS支持數據類型時,IMPORT過程才能導入數據。 SAS支持數字和字符類型的數據,但不支持(例如)二進制對象。 如果要導入的數據是SAS不支持的類型,則IMPORT過程可能無法正確導入。 在許多情況下,該過程嘗試將數據轉換為其最優。 但是,某些類型無法進行轉換。
默認情況下,IMPORT過程將分隔文件讀取為不同的記錄長度文件。 如果外部文件具有固定長度格式,請使用帶有INFILE語句的SAS DATA步驟,該語句包含RECFM = F和LRECL =選項。
對於分隔文件,掃描前20行以確定變量屬性。 您可以使用GUESSINGROWS =語句增加掃描的行數。 所有值都以字符串形式讀入。 如果可以將日期和時間格式或數字信息應用於數據值,則將類型聲明為數字。 否則,類型仍然是字符。
TABLE="tablename"
指定輸入DBMS表的名稱。 如果名稱不包含特殊字符(如問號),小寫字符或空格,則可以省略引號。 請注意,DBMS表名稱可能區分大小寫。
您必須擁有用於PC文件的SAS / ACCESS接口的許可才能導入到DBMS表。
導入DBMS表時,必須指定DBMS =選項。
REPLACE
覆蓋現有的SAS數據集。 如果省略REPLACE,則IMPORT過程不會覆蓋現有數據集。
DATAROW聲明
開始從分隔文本文件中的指定行號讀取數據。
默認值:當GETNAMES = NO:1時,GETNAMES = YES:2
當GETNAMES = NO時,DATAROW必須等於或大於1當GETNAMES = YES時,DATAROW必須等於或大於2。
DATAROW語句僅對分隔文件有效。
語法:datarow = n;
指定輸入文件中的行號,以便IMPORT過程開始讀取數據。
DELIMITER 聲明
指定用於分隔輸入文件中的數據列的分隔符。默認為空格
如果指定DBMS = DLM,則還必須指定DELIMITER =語句。
語法:DELIMITER=char | 'nn'x;
指定用於分隔輸入文件中的數據列的分隔符。 您可以將分隔符指定為單個字符或十六進制值。 例如,如果數據列由&符號分隔,請指定DELIMITER ='&'。
如果省略DELIMITER =,則IMPORT過程假定分隔符是空格。
GETNAMES聲明
指定IMPORT過程是否根據輸入文件第一行中的數據值生成SAS變量名稱。默認是YES
僅對IMPORT過程有效。
如果使用VALIDVARNAME = ANY,則GETNAMES =可能不會將下划線作為數據值的前綴。
GETNAMES語句僅對分隔文件有效。
語法:GETNAMES=YES | NO;
YES指定IMPORT過程從導入的分隔文件的第一行中的數據值生成SAS變量名稱。
NO指定IMPORT過程生成SAS變量名稱為VAR1,VAR2等。
表示IMPORT過程在輸入文件中掃描的行數,以確定適當的數據類型和變量長度。 范圍是1到2147483647(或MAX)。 掃描數據進程從第1行掃描到GUESSINGROWS選項指定的數字。
可以指定而不是2147483647。指定最大值可能會對性能產生負面影響。
此示例導入以下分隔的外部文件,並創建名為WORK.MYDATA的臨時SAS數據集:
Region&State&Month&Expenses&Revenue
Southern&GA&JAN2001&2000&8000
Southern&GA&FEB2001&1200&6000
Southern&FL&FEB2001&8500&11000
Northern&NY&FEB2001&3000&4000
Northern&NY&MAR2001&6000&5000
Southern&FL&MAR2001&9800&13500
Northern&MA&MAR2001&1500&1000
;
程序說明
設置系統選項NODATE選項禁止在輸出中顯示日期和時間。 LINESIZE =選項指定輸出行長度,PAGESIZE =選項指定輸出頁面上的行數。
options nodate ps = 60 ls = 80;
指定輸入文件。指定輸入文件是分隔文件。 替換數據集(如果存在)。 識別輸出SAS數據集。
proc import datafile ="C:\Users\xujia\Desktop\delimiter.txt"
DBMS= DLM
OUT = MYDATA
Replace;
將分隔符指定為&(&符號)。
delimiter= '&';
從第一行數據生成變量名稱。
getnames=yes;
Run;
打印出輸出數據集。
proc print data = mydata;
Run;
示例2:使用Fileref導入特定的分隔文件
此示例導入以下以空格分隔的文件,並創建名為Work.States的臨時SAS數據集。
Region State Capital Bird
South Georgia Atlanta 'Brown Thrasher'
South 'North Carolina' Raleigh Cardinal
North Connecticut Hartford Robin
West Washington Olympia 'American Goldfinch'
Midwest Illinois Springfield Cardinal
示例3:導入制表符分隔文件
此示例導入以下制表符分隔文件,並創建名為Work.Class的臨時SAS數據集。
由於DATAROW =選項規范,第一行讀取將是第5行。
Datarow行= 5;
指定分隔符。在ASCII平台上,選項卡的十六進制表示為'09'x。 在EBCDIC平台上,選項卡的十六進制表示為'05'x。
delimiter='09'x;
run;
示例4:使用CSV擴展名導入逗號分隔文件
此示例導入以下以逗號分隔的文件,並創建名為Work.Shoes的臨時SAS數據集。
指定輸入數據文件。如果存在,則放置數據集。 指定輸出數據集。
將GETNAMES =選項設置為"no"會導致不使用記錄1中的變量名稱。
此外還可以對Excel 以及access數據進行導入:
1 對Excel數據進行導入
PROC IMPORT OUT= WORK.C
DATAFILE= "D:\lol.xls"
DBMS=EXCEL REPLACE;
SHEET="Sheet1$";
GETNAMES=YES;
MIXED=NO;
SCANTEXT=YES;
USEDATE=YES;
RUN;
MIXED=YES | NO;
將數字數據值轉換為包含混合數據類型的列的字符數據值。 此選項僅在從Excel導入數據時有效。 默認值為NO,這意味着數字數據將作為缺失值導入到字符列中。 如果MIXED = YES,則引擎將為該列分配SAS字符類型,並將所有數值數據值轉換為字符數據值。 此選項僅在將數據讀取(導入)到SAS時有效。
SCANTEXT=YES;
會自動掃描,以最大的寬度作為改列字符變量的寬度。如果SCANTEXT=NO,則在不設定TEXTSIZE的情況下,默認長度為255。
USEDATE=YES;
使用日期變量。USEDATE=NO時,默認輸入的將是日期時間變量,時間為該日的0點0分0秒。
對access數據進行導入
PROC IMPORT OUT =ACE
TABLE='ZED'
DBMS=ACCESS REPLACE;
DATABASE='C:\Users\xujia\Desktop\LOL.mdb'
UID='ADAM';
PWD='DEMAXIYA';
RUN;
2.3.4 INFILE導入數據
INFILE指定要使用INPUT語句讀取的外部文件。
語法
INFILE file-specification <device-type> <options> <operating-environment-options>;
INFILE DBMS-specifications;
示例:
data lol;
Infile'c:\zed.dat'dlm = ',';
Input name $ age;
run;
若要創建永久數據及,需要指定二級數據集名稱。例如:
libname mylol 'd:\hero';
data mylol.honor;
Infile 'c:\zed.dat'dlm =',';
Input name $ age;
Run;
例1:
讀取路徑c:\myrawdata\下的數據文件toadjump.dat
代碼:
運行結果:
注:(1)Nosiy 的數據溢出到第二行了,但並不影響,SAS會按照變量順序自動跳到下一行讀取;
-
程序將不加選擇的朱行朱列的讀入所有數據記錄。
Infile 還可以加上可選參數,
MISSOVER 選項(處理每行數據個數長短不一)
Input語句中輸入幾個變量,SAS在觀測值中就讀取幾個變量,如果一行未讀完,則進入下一行直到輸入的變量都讀取了變量值。可以讓SAS不進入下一行讀取,未賦值的變量設為缺失值。
例2:
讀入下面數據 c:\myrawdata\allscores.dat 一個學生應該有5門課成績,但由於最后兩門是自學課程,不是所有學生都完成,故而缺失。此時需要加上MISSOVER。
代碼:
運行結果:
DLM和DSD選項
默認讀入的數據是空格分隔,若是其它分隔符分隔,在infile語句中機上DLM='分隔符':
逗號分隔--DLM=','
制表符分隔--DLM='09'X (制表符的十六進制是09)
有時后面需要再加上DSD,有三個作用:
-
忽略引號中數據的"假分隔符"
-
自動將字符串中的引號去掉;
-
將兩個相鄰的分隔符當做缺失值來處理。
例3 :
讀取路徑 c:\myrawdata\ 下的數據文件bands.csv,內容如下:
注意第三行引號中的逗號並不是分隔符,另外,每行數據長短不一樣,
所以還需要機上MISSOVER。
代碼:
運行結果:
FIRSTOBS= M OBS=N 選項
有的數據文件包括數據的描述,需要用該選項告訴SAS從第m行開始讀取到第n行結束。
例4 讀取如下的數據文件 c:\myrawdata\icegreamsales2.dat :
注意第3行到第5行是有效數據。
代碼:
運行結果:
讀取固定列排列的數據
-
同一變量的值都占據相同范圍的列內;
-
變量值是字符串或者標准數值。
注:標准數據是指數據、小數點、正負號、和科學計算法的 E。逗號數據和日期都不是標准數值。比第一種的優勢在於:
· 不要求變量值之間有空格;
· 缺失值可以直接用空格代替;
· 字符串中可以包含空格;
· 可以以跳過不需要的變量。
語法
Input 變量1 n-m;
注:"n-m"表示變量1數據所占的列范圍,第n列至第m列。
示例:
Input name $ 1-10 age 11-13 height 14-18;
標准按固定排列的數據
例5:
讀取路徑 c:\myrawdata\ 下的數據文件 onionring.dat,內容如下:
代碼:
運行結果:
TRUNCOVER 選項
使用固定列的input 或控制格式(下節)的input輸入時,若某行的數據(+空格)沒有占到指定列的寬度,可能會轉到下一行讀取,此時必須用TRUNCOVER選項,以避免這種錯誤發生。
例6:
讀取如下數據(c:\myrawdata\address.dat)
注意三行的長度都不一樣,input中只能指定最長的一行。
代碼:
運行結果:
讀取非標准格式的數據文件
非標准格式的數據,包括日期數據、"8,796,432"、美元符號$、十六進制數等。
語法:
Input 變量名 變量格式,,;
示例:
Input name $ 10. age 3. height 5.1 birthdate mmddyy10. ;
例7:
讀取路徑 c:\myrawdata\ 下的數據文件 pumpkin.dat, 內容如下:
代碼:
運行結果:
程序說明:
-
"Name $ 10."表示字符型變量Name,共占10列寬度,無小數位;
-
"Heright 5.1"表示數值型變量Height,共占5列寬度,其中1位小數位;
-
"+1"表示跳過一列,即原始數據中Age后面有一個空格;
-
"MMDDYY10."共占10位的日期格式;
-
Score1 -Score5 五個變量格式相同,可以用小括號共同指定格式;
通常可以混合使用前面的三種方式,例如
例8 讀取路徑 c:\myrawdata\ 下的數據文件 natpark.dat ,內容如下:
代碼:
運行結果:
程序說明:
符號"@"是列指示器,"@40"告訴SAS在讀取Acerage變量之前,移動到第40列去;若沒有"@40",Comma9 告訴SAS讀取9列,將會讀取包括空格在內的9列,這便會導致輸出結果有問題:
2.3.5 INPUT 語句
直接輸入
注:單個@ 使sas停留在下一個input語句不換行
兩個@ 使sas停留在下一次data步也不換行
使用INFILE語句引用包含數據的數據文件后,需要指定有關數據排列方式的以下信息:
· 變量的數量及其名稱
· 每個變量的類型,數字或字符
· 每個變量值的格式
· 與每個變量對應的列
換句話說,您必須指定如何讀取數據。
INPUT語句描述輸入記錄中值的排列。 INPUT語句從先前執行的INFILE語句中指定的文件中讀取記錄,將值讀入SAS / IML變量。
有兩種方法可以在SAS / IML INPUT語句中描述記錄的值:
列表(或掃描)輸入
格式化輸入
以下是類數據文件的有效INPUT語句的幾個示例,當然,這取決於數據的存儲方式
如果數據在字段之間以空格或逗號存儲,則可以使用列表輸入。 例如,類數據文件的INPUT語句可能如下所示:
Infile inclass;
Input name $ sex $ age height weight;
這些語句指定以下內容:
· 有五個變量:NAME,SEX,AGE,HEIGHT和WEIGHT
· 數據字段以逗號或空格分隔。
· NAME和SEX是字符變量,用美元符號($)所示。
· AGE,HEIGHT和WEIGHT是數值變量,所以不用。
數據必須以與INPUT語句中列出的變量相同的順序存儲。 否則,您可以使用特定於列的格式化輸入。 格式化輸入是最靈活的,可以處理任何數據文件。 類數據文件的INPUT語句可能如下所示:
Infile inclass;
Input @1 name8. @10 sex $char1. @15 age 2.0
@20 height 4.1 @25 weight 5.1;
這些語句指定以下內容:
·NAME是一個字符變量; 它的值從第1列開始(由@ 1表示)並占用8列($ CHAR8。)。
·SEX是一個字符變量; 其值可在第10列($ CHAR1。)中找到。
·AGE是一個數值變量; 它的值在第15和16列中找到,沒有小數位(2.0)。
·HEIGHT是在第20列到第23列中找到的數字變量,隱含一個小數位(4.1)。
·WEIGHT是第25到29列中的數字變量,隱含一個小數位(5.1)。
接下來的部分將討論這兩種輸入模式。
List Input
如果數據以逗號或數據字段之間的一個或多個空格記錄,則可以使用列表輸入來讀取數據。 如果您缺少值 - 即未知值 - 它們必須用句點(.)而不是空白字段表示。
當SAS / IML語言查找值時,它會跳過空格和制表符。 然后它會掃描該值的分隔符。 分隔符是空白,逗號或記錄的結尾。 使用&符號(&)格式修飾符時,SAS / IML會查找兩個空格,一個逗號或記錄的結尾。
用於列表輸入的INPUT語句的一般形式如下:
INPUT variable <$> <&> <…variable <$> > <&> >;
Variable
命名要由INPUT語句讀取的變量。
$
表示前面的變量是字符。
&
表示字符值可以包含一個嵌入的空白。 因為空白通常表示數據值的結尾,所以使用&符號格式修飾符以至少兩個空格或逗號表示值的結尾。
通過列表輸入,SAS / IML掃描輸入行的值。 在以下情況下考慮使用列表輸入:
當空格或逗號分隔輸入值時
當句號而不是空格表示缺失值時
在幾種情況下,列表輸入是默認值。 這些情況的描述和SAS / IML的行為如下:
如果沒有為變量指定輸入格式,則SAS / IML會掃描數字。
如果指定了單個美元符號或&符號格式修飾符,則SAS / IML會掃描字符值。 &符號格式修飾符可以實現單個嵌入空格。
如果格式未指定或為零,則SAS / IML會掃描第一個空格或逗號。
使用列表輸入讀取時,INPUT語句中列出的變量的順序必須與數據文件中值的順序一致。 例如,請考慮以下數據:
Alice f 10 61 97
Beth f 11 64 105
您可以使用列表輸入通過指定以下INPUT語句來讀取這些數據:
Input name $ sex $ age height weight;
該陳述暗示變量按給定的順序存儲。 也就是說,每行數據按該順序包含學生的姓名,性別,年齡,身高和體重,並至少用空格或逗號分隔。
Formatted Input
列表輸入的替代方法是格式化輸入。 讀取格式化輸入的INPUT語句必須在每個變量后面都有一個SAS信息。 信息提供輸入值的數據類型和字段寬度。 格式化輸入可與指針控件和格式修飾符一起使用。 但是,格式化輸入既不需要指針控件也不需要格式修飾符。
指針控制功能
指針控件重置指針的列和行位置,並告訴INPUT語句去哪里讀取數據值。 您可以使用指針控件指定要從中讀取的列和行:
· 列指針控件將指針移動到指定的列。
· 行指針控件將指針移動到下一行。
· 行保持控件使指針保持在當前輸入行。
· 二進制文件指示符控件指示輸入行來自二進制文件
列指針控制
列指針控制指示輸入值從哪一列開始。 列指針控件以at符號(@)或加號(+)開頭。 完整列表如下:
@n
將指針移動到n列。
@點變量
將指針移動到由point-variable的當前值指定的列。
@(表達式)
將指針移動到表達式值給定的列。 表達式必須求值為正整數。
+ N
將指針移動n列。
+點可變
將指針移動到由point-variable值給出的列數。
+(表達式)
將指針移動到由expression值給出的列數。 表達的值可以為正負。
以下是使用列指針控制的一些示例:
在前面使用格式化輸入的示例中,您使用了多個指針控制。 以下是陳述:
infile inclass;
input @1 name $char8. @10 sex $char1. @15 age 2.0
@20 height 4.1 @25 weight 5.1;
@ 1將指針移動到第1列,@ 10將指針移動到第10列,依此類推。 將指針移動到數據字段開始的列,然后提供指定變量占用的列數的信息。 INPUT語句也可以寫成如下:
input @1 name $char8. +1 sex $char1. +4 age 2. +3 height 4.1
+1 weight 5.1;
在此表單中,將指針移動到第1列(@ 1)並讀取8列。 指針現在位於第9列。現在,將指針+1列移動到第10列以讀取SEX。 informat要讀取占據一列的字符變量。 在讀取SEX的值后,指針位於第11列,因此使用+4將其移至第15列,並在第15和16列中讀取AGE。 指針現在位於第17列,因此移動+3列並讀取HEIGHT。 同樣的理念適用於閱讀重量。
2.3.6 DDE 方法
DDE是一種傳統方法,SAS不鼓勵使用DDE。 相反,請考慮較新的SAS功能支持的替代方案。
當您現代化到集中式SAS環境時,請注意幾個挑戰。 例如,如果您的SAS會話在遠程計算機(通常是未在Windows上運行的計算機)上運行,則SAS無法使用DDE與本地Microsoft Excel應用程序進行通信。 DDE僅在同一台計算機上的兩個Windows進程(SAS和Excel)之間工作。
但是,只要您將SAS軟件及其DDE合作伙伴(通常是Microsoft Excel)置於同一台Windows PC上運行,使用DDE的SAS程序仍然可以正常工作。
如果您的進程依賴於DDE但需要在很短的時間內轉移到客戶端/服務器SAS環境,請采用以下方法。 使用SAS for Windows維護指定的計算機以執行DDE基本工作,即使將其他進程移至企業SAS環境也是如此。
動態數據交換(DDE)是一種在Windows應用程序之間動態交換信息的方法。 DDE使用客戶端/服務器關系使客戶端應用程序能夠從服務器應用程序請求信息。 SAS始終是客戶。在此角色中,SAS從服務器應用程序請求數據,將數據發送到服務器應用程序或向服務器應用程序發送命令。
您可以將DDE與DATA步驟,SAS宏工具,SAS / AF應用程序或請求和生成數據的SAS的任何其他部分一起使用。 DDE有許多潛在用途。一種用途是從Windows電子表格或數據庫應用程序中獲取數據。
您可以通過訪問以下URL來訪問動態數據交換(DDE)支持的應用程序。支持Word和Excel應用程序。不支持PowerPoint應用程序。
注意:許多Windows程序(包括SAS)現在都支持OLE以促進應用程序之間的通信。如果需要與支持OLE的應用程序共享數據,您可能更喜歡使用SAS內置的OLE支持。有關更多信息,請參閱關於OLE。
要在SAS中使用DDE,請使用以下語法發出FILENAME語句:
FILENAME fileref DDE 'DDE-triplet' <DDE-options>;
fileref
是一個有效的fileref(如引用外部文件中所述)。
DDE
是設備類型關鍵字,告訴SAS您要使用動態數據交換。
'DDE-triplet'
是DDE外部文件的名稱。
DDE示例概述
本節提供了在Windows下使用DDE和SAS的幾個示例。 這些示例使用Microsoft Excel和Microsoft Word作為DDE服務器,但任何支持DDE作為服務器的應用程序都可以與SAS通信。
在運行這些示例之前,必須先調用Microsoft Excel和Microsoft Word,然后打開示例中使用的電子表格或文檔。
注意:DDE示例包含在您從"幫助"菜單訪問的特定於主機的示例程序中。
使用X命令打開DDE服務器
可以使用SAS代碼中的X命令打開DDE服務器應用程序。 必須關閉XWAIT和XSYNC選項。
選項noxwait noxsync;
x '"C:\program files\microsoft office\office14\excel.exe"';
如果路徑包含空格,則路徑周圍需要雙引號。 單引號用於X命令。
使用DDE從Microsoft Excel讀取數據
您可以使用DDE將Excel應用程序中的數據讀入SAS,如下例所示:
filename monthly
dde 'excel|sheet1!r1c1:r10c3';
data monthly;
infile monthly;
input var1 var2 var3;
run;
proc print;
run;
使用DDE從Microsoft Word讀取數據
此示例從給定書簽的Microsoft Word文檔中讀取數據。
filename testit dde 'winword|"c:\temp\testing.doc"
!MARK' notab;
libname workdir 'c:\temp';
/* Get ready to read the first bookmark. */
data workdir.worddata;
length wordnum $5;
infile testit;
input wordnum $;
run;
proc print;
run;
閱讀遺漏數據
此示例說明從名為SHEET1的Excel電子表格中讀取缺少的數據。 此示例讀取第1列到第3列以及第10行到第20行中的數據。某些數據單元可以為空白。 以下是一些數據的示例:
...
10 John Raleigh Cardinals
11 Jose North Bend Orioles
12 Kurt Yelm Red Sox
13 Brent Dodgers
...
以下是可以將這些數據正確讀取到SAS數據集中的代碼:
filename mydata
dde 'excel|sheet1!r10c1:r20c3';
data in;
infile mydata dlm='09'x notab
dsd missover;
informat name $10. town $char20.
team $char20.;
input name town team;
run;
proc print data=in;
run;
在此示例中,NOTAB選項告訴SAS不要將從Excel應用程序發送的選項卡轉換為空白。因此,制表符可用作數據值之間的分隔符。 DLM =選項指定分隔符,'09'x是制表符的十六進制表示。 DSD選項指定兩個連續的分隔符表示缺失值。默認分隔符是逗號。有關DSD選項的更多信息,請參閱SAS系統選項參考。如果SAS程序在所有INPUT語句變量的當前行中找不到值,則MISSOVER選項會阻止SAS程序進入新的輸入行。使用MISSOVER選項,當INPUT語句到達當前記錄的末尾時,預期但未找到的值將設置為缺失。
INFORMAT語句強制DATA步驟使用修改后的列表輸入,這對此示例至關重要。如果您不使用修改列表輸入,則會收到不正確的結果。使用修改后的列表輸入的必要性不是DDE特定的。即使您在CARDS或DATALINES語句中使用數據,無論數據是空白還是逗號分隔,您都需要它。
2.3.7 sas pipe
什么是管道?
管道使您的SAS應用程序能夠從任何寫入標准輸出的UNIX命令接收輸入,並將輸出路由到從標准輸入讀取的任何UNIX命令。 在UNIX命令中,管道由豎線(|)表示。 例如,要查找目錄中的文件數,可以通過管道將ls命令的輸出重定向到wc(字數)命令:
ls | wc -w
命名管道簡介
命名管道功能是Windows中用於與其他應用程序通信的SAS中最強大的工具之一。 命名管道功能可以在同一台計算機上的應用程序或網絡上不同計算機上的應用程序之間進行雙向數據或消息交換。
在SAS實際工作中經常會遇到需要批量導入某文件夾下的所有excel文件,或者需要讀取某文件夾下最新的文件。這種情況下即需要掃描文件夾下的所有文件,以便於后續程序的批量操作或者判斷,我們可以掃描讀取文件夾下所有文件名稱:利用pipe管道來實現。
pipe管道方法無需其他的函數參與,僅需要filename和pipe即可實現。
例子:
現在需要讀入"D:\user\input\"文件夾下的所有xls后綴文件名。
程序:
filename msg pipe "dir D:\user\input\*.xls /b /s"; /*/b /s是dos中的命令,/b表示使用空格式即只輸出文件名,/s表示文件夾下的子文件夾的所有文件也進行掃描*/
data temp_excel;
infile msg;
length myname $200.; /*定義myname的格式以及長度*/
input myname;
run;
至此,生成的temp_excel數據集中即包含"D:\user\input\"路徑下的所有xls后綴的文件名。
此外可以在data步加上一些where條件也是可以的。
比如:只想讀取包含"銷售日報"的文件,那么data步只需要稍做修改即可。
data temp_excel;
infile msg;
length myname $200.; /*定義myname的格式已經長度*/
input myname;
if index(myname,"銷售日報") gt 0; /*添加的條件:只選取包含"銷售日報"四個字的文件*/
run;
這里用到的語法如下:
filename <fileref> pipe "<command>";
其中command是DOS命令,pipe將command里面的信息導入虛擬文件fileref里面,再在data步里面調用。例如我們需要讀取電腦里面一個文件夾(D:\TEMP)下面所有的txt文件:
filename temp pipe "D:\TEMP\*.txt /b";
2.3.8 IO 函數
直接I / O是一種處理輸入和輸出文件的方法,用於文件處理。直接I / O使SAS能夠直接從存儲設備讀取文件並將文件寫入存儲設備,而無需先通過UNIX操作環境的讀寫緩存。您可以將直接I / O用於SAS文件。使用直接I / O可能會提高系統性能,具體取決於您運行的作業的數量和類型。
SAS使用三個影響直接I / O的相關選項:
ENABLEDIRECTIO聲明選項
USEDIRECTIO =聲明選項
USEDIRECTIO =數據集選項
LIBNAME語句中的ENABLEDIRECTIO選項使直接I / O處理可用於DATA語句中列出的數據集。指向數據集的libref必須已在使用ENABLEDIRECTIO選項的LIBNAME語句中定義。使用ENABLEDIRECTIO本身不會打開直接I / O.
分配給具有ENABLEDIRECTIO選項的目錄的libref將與沒有ENABLEDIRECTIO選項分配給同一目錄的另一個libref不匹配。兩個libref將指向同一目錄,但使用帶有ENABLEDIRECTIO的libref打開的文件將使用直接I / O讀取和寫入。使用常規磁盤I / O調用將讀取和寫入使用其他libref打開的文件。
DATA語句中的USEDIRECTIO =數據集選項或LIBNAME語句中的USEDIRECTIO =語句選項為已應用ENABLEDIRECTIO語句選項的數據集啟用直接I / O.在不首先應用ENABLEDIRECTIO選項的情況下使用USEDIRECTIO =對數據集中的直接I / O沒有影響。
您可以通過兩種方式打開直接I / O:
在LIBNAME語句中同時使用ENABLEDIRECTIO和USEDIRECTIO =選項。
此方法打開直接I / O LIBNAME語句中libref引用的所有文件。
使用LIBNAME語句中的ENABLEDIRECTIO選項呈現可用的直接I / O,並使用DATA語句中的USEDIRECTIO =數據集選項打開直接I / O功能。
此方法僅針對LIBNAME語句中libref引用的數據集的直接I / O打開。
這種方法導入數據比較少見具體參考SAS help幫助文檔。
2.3.9 Import Wizard 使用導入向導
SAS還可以通過界面導入各種類型的數據
1 點擊 文件>>>導入數據
2 選擇格式
3 選擇好后點擊 NEXT >>>的、選擇文件所在的位置,然后點擊 打開 ,點擊NEXT
4 選擇邏輯庫(默認是WORK)和要生成數據集的名稱(aa),點擊 Finish
然后在WORK邏輯庫中會有aa數據集,窗口日志也會顯示創建成功。至此,數據導入成功!
其它格式數據的導入跟上例類似,請自行操作。