2025年12月11日 星期四

SASPy-讓你腳踩Python地盤呼叫SAS過來支援輸贏的套件

 

SASPy 官網 SASPy | SAS Support
由SAS官方親自開發的Python套件。有了它,在Python IDE軟體內寫Python程式碼時,可隨時穿插SAS程式碼召喚SAS這頭魔獸快速搞定Python弱項領域(例如SAS Proc SQL高效串檔計算或執行什麼都有什麼都不奇怪的統計分析法)。就如片頭旨揭所示:Everything is better with friends.

影片中展示的Python IDE環境為JupyterLab,直接網頁上撰寫程式碼,類似IDE還有Jupyter Notebook和Google的Colab。  

===以Spyder v6.1.0 (conda)示範===
1.開啟Spyder軟體(我慣用的Python IDE環境,可自Anaconda Navigator途徑下載,見另篇文章)
2.在軟體控制台視窗內輸入 pip install saspy,如下:

看見Success表示安裝成功。或者可下段輸入 pip list,顯示目前已安裝的套件和版本。
3. 若您上我的Python課程或看我的著作時,先前已看到我於Milanote公布欄發布的課前資訊而下載安裝,則課前一天可嘗試pip看看有否新版可安裝。同樣於下段輸入 pip install --upgrade saspy

過來分兩條路徑走(擇一):

A路徑(你的電腦有安裝地端租賃SAS軟體)
設定最簡單。
先確定你電腦內的Java安裝在哪(若沒安裝,要先安裝)。


啟動命令提示字元app後,輸入where java再按enter即可得知。


若你的Java和SAS安裝路徑與我不同,程式碼內的路徑應一併修改。

執行以下程式碼,看SASpy套件的設定檔存放在哪
import saspy
print(saspy.SAScfg)

得到   C:\Users\cingc\AppData\Roaming\Python\Python311\site-packages\saspy\sascfg_personal.py
打開sascfg_personal.py,預設內容全刪並換成以下內容(留意你的java安裝路徑):
SAS_config_names = ['saslocal']
saslocal = {
    'java'      : r'C:\Program Files (x86)\Common Files\Oracle\Java\java8path\java.exe',  # Java 路徑
    'saspath'   : r'C:\Program Files\SASHome\SASFoundation\9.4\sas.exe',  # SAS 9.4 執行檔路徑
    'encoding'  : 'utf-8'
}

若syspy資料夾內無該.py檔案,則Spyder開一分頁,把上述程式碼貼入,再另存成sascfg_personal.py並移到上述saspy資料夾內。
Spyder另開一分頁,執行以下程式碼
import saspy
sas_obj2 = saspy.SASsession(cfgname='saslocal',results='TEXT')

第一次執行會跳出此視窗,按允許

出現以下內容,表示Spyder內的Python已與地端SAS連接成功。

註: results='TEXT'目的:
Spyder 執行 SASPy 時,會把 SAS 回傳的 ODS HTML / LISTING 訊息渲染成大量純文字,看起來像亂碼,但其實內含HTML標籤、CSS、SAS log、Base64 圖片、GMAP metadata 等。
就像這樣:
這些會塞滿 Spyder console。
results='TEXT'讓 SASPy 不要把 HTML 回傳到 Spyder,只回傳純文字 log(意即不會再有上圖紅框內資訊)

過來我們在Spyder地盤執行一段SAS程式碼(製造數據檔):
sas_obj2.submit("""
data mouse;
input treat $n;
do block=1 to n;
input y@@;
output;
end;
cards;
A1 2
12 18
A2 3
14 12 13
A3 3
19 17 21
A4 2
24 30
;run;
""")

Output出上述內容,表示已成功。

然後再執行以下程式碼(以一般線性模型簡易評估):
sas_obj2.submit("""
ods html path='C:/py/Spyder_outcome/' 
               gpath='C:/py/Spyder_outcome/' 
               file='glm.html' style=HTMLBlue;
ods graphics on;
proc glm data=mouse plots=all;
    class block treat;
    model y = block treat;
    means block treat / snk;
    means treat / dunnett('1');
run;
ods graphics off;
ods html close;
""")

成果如下:


當不再連線SAS就執行以下程式碼斷線:
sas_obj2.endsas()

後記(程式碼再造):
因為跑完還得手動開檔案,且跑統計分析時常會調整參數後再跑數遍看調整結果,所以跑前最好清除先前跑出的檔案。所以再於主程式碼前後各加一段,如下:
#先把Spyder_outcome資料夾內的文件(不含其內的資料夾)逐一刪除
import os
import glob
folder = "C:/py/Spyder_outcome/"
files = glob.glob(folder + "*")
for f in files:
    try:
        os.remove(f)
    except:
        pass

sas_obj2.submit("""
ods html path='C:/py/Spyder_outcome/'  
               gpath='C:/py/Spyder_outcome/'  
               file='glm.html' 
               style=HTMLBlue;
ods graphics on;
proc glm data=mouse plots=all;
    class block treat;
    model y = block treat;
    means block treat / snk;
    means treat / dunnett('1');
run;
ods graphics off;
ods html close;
""")
import os
os.startfile("C:/py/Spyder_outcome/glm.html")
這樣跑完就會自動開檔並切換畫面。

若要連Spyder_outcome資料夾內的子資料夾也一併刪除(原理: 刪除Spyder_outcome資料夾,再建一個Spyder_outcome資料夾),則換成如下程式碼:
import shutil
shutil.rmtree("C:/py/Spyder_outcome/", ignore_errors=True)
os.mkdir("C:/py/Spyder_outcome/")


B路徑(你的電腦沒有安裝地端租賃SAS軟體,但有帳密能登入雲端SAS Studio)
關於雲端SAS Studio,帳號申請方法見此(執行B路徑的必要條件)。

執行以下程式碼,看SASpy套件的設定檔存放在哪
import saspy
print(saspy.SAScfg)

得到   C:\Users\cingc\AppData\Roaming\Python\Python311\site-packages\saspy\sascfg_personal.py
打開sascfg_personal.py,預設內容全刪並換成以下設定(注意你的java安裝路徑,你可能會和我的不同,方法見前述CMD查詢法):
SAS_config_names=['oda']
oda = {'java' : 'C:\Program Files (x86)\Common Files\Oracle\Java\java8path\java.exe',
#Asia Pacific Home Region 1
'iomhost' : ['odaws01-apse1.oda.sas.com','odaws02-apse1.oda.sas.com'],
'iomport' : 8591,
'encoding' : 'utf-8'
}

儲存關閉。再執行以下程式碼:
import saspy
sas_obj = saspy.SASsession()

出現user id: 就輸入上述帳號並按enter, 之後會再出現 password for QMR user: 就換輸入密碼並按enter, 待看到 SAS Connection established. Subprocess id is ......,表示已連線成功。

接下來一樣傳送出一串SAS程式碼(製造數據檔):
sas_obj.submit("""
data crosstable;
do i=1 to 2;
do j=1 to 2;
input f @@;
output;end;end;
datalines;
30 10 11 49
;run;
""")

Output出上述內容,表示已成功。
過來把SAS製造出來的dataset透過sasdata2dataframe轉成dataframe(Python套件-Pandas的資料集)
執行以下程式碼(conda內的Spyder已內建Pandas,故不用再pin):
df = sas_obj.sasdata2dataframe(table='crosstable', libref='WORK')
print(df)

確實得到此dataframe。
同樣的SAS程式碼,在地端SAS執行結果。

當不再連線SAS就執行以下程式碼斷線。
sas_obj.endsas()

所以若要用SAS清理或統計分析,得將資料轉成SAS的dataset型式,若要用Python處理數據得將資料轉成Pandas的dataframe型式,他們可透過函數 sd2df和df2sd互轉,2就是to,上述的sasdata2dataframe可用簡寫sd2df取代,另一也同。


延伸閱讀:

若要copy the code,請至Github

如果本文章提供的資訊對你有幫助,可以考慮請我喝飲料(金額隨喜),謝謝。
台新銀行帳戶 (備註: saspy1)

沒有留言: