怎樣優雅地學好 SAS 與 R 語言?


優雅學習使用SAS的秘訣在於 1.Data Step 2.Proc SQL 3.Proc IML 3.Macro 4. ODS 各種畫圖 GTL

1.Data Step. 很多人開始以為Data Set 只是讀讀數據,改改數據用的,其實它的功能異常強大。你可以在裡面調用函數和宏,可以使你的程序高度定製化和自動化,提供一些編程語言的功能。

2.Proc SQL. 真的真的很好用,處理數據一大利器! 很多情況下,把數據整理好需要半天,然後你跑個回歸就1分鐘....

3.Proc IML. 已經越來越好用了。不過很多情況下,其實用不著自己去寫矩陣運算。

4.Macro. 用宏容易上癮,最好什麼過程都能一步到位,改幾個輸入參數就能完成所有工作。

5. ODS 各種畫圖 GTL . SAS畫圖也有很高的定製性和自由度,但是它的圖偏向商業和學術,看起來非常嚴肅的樣子,而且畫的圖像素很高,質量極佳。你可以按照不同的需求來定製你的輸出,最低的程度是僅僅改變圖的style(多得嚇人),最高程度是用GTL,可以畫出令人吃驚的印刷級別的圖。

至於其他各種統計 Proc,對照官方文件用就行,只有你不懂統計,沒有你不會使用Proc。

SAS核心的在於企業用戶的那些模塊,有些是商業機密...


優雅的學好SAS與R語言並不是非常困難的事情,因為兩個語言或工具的區別非常明顯,不至於接近到容易混淆。

首先,我們需要做一些簡單地入門,來體會一下兩個語言的」做事風格「有何差異。

如果做過簡單地上手練習,就會發現SAS語言的結構更簡單,在代碼風格規範的情況下表達力和可讀性更強,代碼分為數據步(DATA STEP)和過程步(PROC STEP),分工明顯,完成一個任務時像是在告訴電腦做什麼(What to do)而不是怎麼做(How to do)。相比之下,R的代碼更接近於傳統意義上的命令式編程(imperative programming),變數、循環、函數等等。

我們需要理解,在不同場合使用更加合適的工具,可以提高我們的生產力。例如,用SAS做快速建模、大批量模數據處理都是很好的選擇,用R做偏向編程和涉及很多統計方面的工作也是較好的選擇。

在各自具有優勢、更加易用的領域去學習這兩個工具,是比較容易也比較有效的,秉持的原則就是在合適的場合使用合適的工具。把握住兩個語言「行事風格」的差異,就更容掌握這兩個工具,就好象把握住兩個朋友的」行事風格「的差異和個人特徵,就更容易認識他們而不至於混淆。

接下來,就是慢慢積累了,在基礎練習的基礎上可以用項目和複製論文來練手。


看到優雅我就笑了...想要學好任何東西都只有一個途徑, get your hands dirty.


學完data步、最基本的proc步以及宏後,立刻去看call execute(command string);的用法。

所謂優雅在於關鍵的兩點:通過data步實現多宏變數的賦值傳遞與批量的宏程序執行。

有了這個大招後,data步一下子就變得上天下地無所不能,代碼會非常簡化並批量運行。你以後要做的就是根據工作需求寫一堆自定義宏,建立自己的宏程序庫,主流的數據處理基本能手到擒來。

鏈接:

關於CALL EXECUTE()

call execute學習小結分享

PS:

要做到批量執行宏,通常需要將數值型變數轉化為字元串並整合為command字元串,往往需要用「三基友函數」(put, tranwrd, catt),他們分別可以實現數字轉字元串、字元串內部替換、字元串截尾連接。之所以要說批量執行宏,而不是執行程序,是因為你可以將大量的程序封裝到宏程序中,然後只在command字元串中寫入簡短的宏程序名即可。而且宏程序名還可以作為宏變數,再嵌套一層宏程序來封裝。

注意:call execute(『%』||『let var=……;』);與call symputx("var",……);略有不同。


分享一個R語言進階教程。感謝 @任坤老師的貢獻。

[原]數據流編程教程:R語言與非結構化數據共舞

介紹

現代化數據科學中的 DataFrame 概念源起R語言,而 Python Pandas 和 Spark DateFrame 都是參考R設計的。不過在實際的網路數據通訊中,類似DateFrame這樣的格式卻並不是主流,真正主流的方式其實是JSON(JavaScript Object Notation ),所以討論如何處理非結構化數據就變得非常有意義了。加之,近年來 Redis、MongoDB、ELK等非結構化資料庫的繁榮,MySQL 5.7之後也已經添加了對JSON格式的原生支持(之前可以用blob、longtext等格式存儲),非結構化數據更是在數據處理中變得流行。

本文將從 非結構化數據的轉化、處理以及可視化三個方面討論如何在R中操作非結構化數據。

數據清洗:JSON、List、DataFrame的三國殺

DataFrame 是R中的結構化數據結構,List 是R中的非結構化數據。JSON、List、DataFrame三者之間的互相轉化是數據科學中非常頻繁的一類操作。

在R中有一個非常有意思的現象,那就是處理json時,我們有三個選擇,jsonlite、rjson以及RJSONIO,三者各有特點,有時為了處理一些問題還必須得混合使用。在實際處理字元串中,一定要注意的就是R中字元串的轉義問題。比如\表示,"表示"等等。我曾經因為Python和R中的雙層JSON解析多次遇到轉義符號的問題。具體可以參看官方手冊。

jsonlite

jsonlite 是我最常用的一個json處理包,因為jsonlite可以一步將 json 轉成 dataframe 再 從dataframe 轉到 json,在數據處理中可以輕鬆解決常見的 json轉化問題。此外,jsonlite 還完美支持utf-8,在 json 字元串錯誤時會有明顯的錯誤提示。

jsonlite 的劣勢是當出現雙層 json 時,jsonlite 會將json轉成dataframe格式的 list,這直接導致我們在用 length() 或者 dim() 求內層 JSON 的維度會出現錯誤。

jsonlite::fromJSON("{"x":"量化投資","y":"harryzhu"}")

$x
[1] "量化投資"

$y
[1] "harryzhu"

rjson

rjson 和 jsonlite最大不同之處在於,rjson將json轉化為一個list,而list是R語言中非結構化數據的事實標準,類似 python 中的 dict,或者 matlab 中的 cell。

值得注意的是,rjson在json轉化中直接保持所有的浮點型數據,而jsonlite和RJSONIO則可以通過參數控制保留若干位小數的精度。

rjson::fromJSON("{"x":"1","y":"2"}")
rjson::toJSON(pi)

$x
[1] "1"

$y
[1] 2

[1] "3.14159265358979"

jsonlite::fromJSON(pi,digit=4)

[1] "[ 3.142 ]"

RJSONIO

RJSONIO 允許傳入沒有轉義符號的 JSON 字元串,並且支持將缺失值(NA)直接轉成 Null,需要小心的是RJSONIO只支持unicode,如果傳入utf-8則會釀成悲劇。

RJSONIO::fromJSON(RJSONIO::toJSON(c(1,2,NA,4)))

"[[1]]
[1] 1

[[2]]
[1] 2

[[3]]
NULL

[[4]]
[1] 4"

更多細節可以參考 A biased comparsion of JSON packages in R

數據處理:List 處理

談到list的處理就不得不談一談 rlist包。rlist包是任坤老師貢獻到CRAN上的,任坤老師既是一個多產的R Developer (pipeR、formattable作者)也是一名量化投資者,目前在做私募方面的創業。想要學習rlist,我們可以參考一下任坤老師的演講:跳出數據框,擁抱非結構化數據和官方教程。

rlist與高階函數

rlist 是支持高階函數表達式的,借鑒了Python、Scala等語言中的MapReduce模型,rlist也為list提供了map、filter、reduce、group、join、search、sort等高級數據操作,熟悉這些操作以後上手sparkR的RDD操作非常有幫助。

示例一:

利用 GitHub API,我們可以知道Hadley 的原創R語言開源項目中討論議題數量最多的10個項目是哪些。

library(rlist)
library(pipeR)
# 分頁讀取數據
repos &<- "https://api.github.com/users/hadley/repos?per_page=100page=%d" %&>&>%
sprintf(1:2) %&>&>%
list.load("json") %&>&>%
list.ungroup

repos %&>&>%
list.filter(has_issues, !fork, language == "R") %&>&>%
list.names(name) %&>&>%
list.mapv(open_issues) %&>&>%
list.sort(-.) %&>&>%
list.take(10)
# dplyr ggplot2 lubridate devtools staticdocs plyr
# 88 72 54 33 32 28
# stringr roxygen3 scales gtable
# 24 22 22 21

示例二:

批量讀取非空 csv 文件並且合併成一個 data frame:

"data/" %&>&>%
list.files("\.csv", full.names = TRUE) %&>&>%
list.filter(file.info(.)$size &> 0) %&>&>%
list.map(read.csv(., header = TRUE, stringsAsFactors = FALSE)) %&>&>%
list.stack

rlist擴展包充分利用了R語言中list對象的特性,定義了一整套函數來幫助用戶靈活快速地按要求處理各種非結構化數據,同時結合pipeR包中管道操作符的使用,使R程序更加具有可讀性,應用更加人性化。

更多操作

下面是rlist中提供的操作:

分類函數映射(Mapping)list.map, list.mapv, list.select, list.iter, list.maps篩選(Filtering)list.filter, list.find, list.findi, list.first, list.last,list.take, list.skip,list.takeWhile, list.skipWhile, list.is,list.which, list.all, list.any, list.count, list.match更新(Updating)list.update排序(Sorting)list.order, list.sort分組(Grouping)list.group, list.ungroup, list.cases, list.class, list.common,list.table合併(Joining)list.join, list.merge搜索(Searching)list.search數據讀寫(I/O)list.parse, list.load, list.save, list.serialize,list.unserialize數據變換list.append, list.prepend, list.reverse, list.zip, list.rbind,list.cbind, list.stack, list.flatten, list.names, list.sample

非結構化數據可視化

為了方便在R中可視化JSON數據,jsonview將js中的jsonviewer庫引入到R中。

我們可以傳入list或者json字元串做非結構化數據的可視化。

library(xmlview)
library(jsonlite)
devtools::install_github("hrbrmstr/jsonview")
jsonview::json_tree_view(fromJSON("https://collector.torproject.org/index.json"))

下面是timelyportfolio提供的一個結合shiny和jsonview的json編輯器的例子:

install.packages("shiny")
devtools::install_github("timelyportfolio/listviewer")
library(shiny)
library(listviewer)

# 數據準備
data(mtcars)

ui &<- shinyUI( fluidPage( jsoneditOutput( "jsed" ) ) ) server &<- function(input,output){ output$jsed &<- renderJsonedit({ jsonedit( as.list( .GlobalEnv ) ,"change" = htmlwidgets::JS("function(){ console.log( event.currentTarget.parentNode.editor.get() ) }") ) }) } runApp( list( ui = ui, server = server ) )

接著,在瀏覽器中的對應埠可以打開這個json編輯器應用。

章節附註

除了JSON之外,和NoSQL資料庫的交互在大數據時代也成為了主流,混合使用Redis、Hive、MongoDB等資料庫也成了家常便飯,具體操作可以翻看張丹老師的R利劍NoSQL系列文章。

參考資料

  • A biased comparsion of JSON packages in R

  • 任坤:跳出數據框,擁抱非結構化數據

  • rlist-tutorial

  • jsonview GitHub

作為分享主義者(sharism),本人所有互聯網發布的圖文均遵從CC版權,轉載請保留作者信息並註明作者 Harry Zhu 的 FinanceR 專欄:FinanceR - SegmentFault,如果涉及源代碼請註明GitHub地址:harryprince (HarryZhu) · GitHub。微信號: harryzhustudio

商業使用請聯繫作者。


話說優雅不應該是旁人眼裡對你的評價嗎?而你自己才知道自己是如何暗搓搓蓬頭垢面努力才能行雲流水輕鬆搞定。學東西出了絕知此事要躬行之外我想不到其他方法

另,能否別用優雅這一詞了啊,在知乎這個詞語已經被「如何優雅。。。」玩壞了= =


大爺的,學軟體還要什麼優雅。


安利一本書:SAS and R, Data Management, Statistical Analysis, and Graphics,作者Ken Kleinman是我非常喜歡的教授。這本書有點像英漢字典,介紹了怎樣分別用SAS和R做同一件事情,如果你同時在用這兩個,對你應該很有幫助。

R和SAS各有優劣,主要的區別在於SAS有一大群人在開發和維護並未客戶解決問題,而R packages基本都是一小撮超級聰明的人自己寫的。用SAS做mixed models絕對是比R全面,但是R在作圖方面完勝SAS。作為搞統計的人,精通SAS和R並且能在兩者間嫻熟轉換還是很有用的,有是有可以兩個都跑一邊看結果是不是一樣在求證自己的方法有沒有對(有時候是不一樣的)。


如果你理解的優雅是像天鵝一般的話,那就是要把手伸進渾水裡拚命的撲騰,也就是樓上所說的get your hands dirty

只用過R的多說兩句,R的優勢在於開源和社區,要多和同道進行交流,至少我很多曾經碰到的初學者問題都能在諸如stackoverflow上找到答案。當然還得依照你的學科領域和實際項目具體問題具體分析


其實大家都沒看到這道題目的本質是——「如何優雅」四字。這很複雜,忽然感覺這道題已經超出編程界,直接延伸到生活、哲學、人生的領域上....好像聯想得太多了,掩面奔走...


提前規劃,按時完成


俗人在學SAS中,每看一行程序有一堆不認識的語句,然後看sas help,每天都在抓耳撓腮拽頭髮。

想優雅的學的話,建議樓主忍住。


請題主告訴我「優雅」是怎麼回事?你是指「萬花叢中過,片葉不沾衣」的境界嗎(這貌似是形容泡妞的啊喂)?學習這東西哪來的優雅?即使一個指法精妙絕倫、造詣高深莫測的鋼琴大師初學的時候,跟他/她成名後的優雅相比,也是笨拙無比、慘不忍睹,每個成功的人都是從爛泥塘子裡面摸爬滾打出來的。【當然題主也可以在學習R和SAS的時候聽聽巴赫的哥德堡變奏曲,泡上一杯貓屎咖啡,這優雅值就蹭蹭地上去了……】


自己乖乖躲家裡學,學會了再出來優雅。


Have fun:

%MACRO a(note, octave, duration);

%IF note="C" %then %let pitch = 262;

%ELSE;

%IF note="C+" %then %let pitch = 277;

%ELSE;

%IF note="D" %then %let pitch = 294;

%ELSE;

%IF note="D+" %then %let pitch = 311;

%ELSE;

%IF note="E" %then %let pitch = 330;

%ELSE;

%IF note="F" %then %let pitch = 349;

%ELSE;

%IF note="F+" %then %let pitch = 370;

%ELSE;

%IF note="G" %then %let pitch = 392;

%ELSE;

%IF note="G+" %then %let pitch = 415;

%ELSE;

%IF note="A" %then %let pitch = 440;

%ELSE;

%IF note="A+" %then %let pitch = 466;

%ELSE;

%IF note="B" %then %let pitch = 494;

%ELSE;

data _null_;

xpitch = pitch * octave;

call sound (xpitch, duration*1.5);

run;

%MEND

%MACRO STARWARS;

%a("G",1,150);

%a("G",1,150);

%a("G",1,150);

%a("D+",1,200);

%a("A+",1,75);

%a("G",1,150);

%a("D+",1,200);

%a("A+",1,75);

%a("G",1,300);

%a("D",2,150);

%a("D",2,150);

%a("D",2,150);

%a("D+",2,225);

%a("A+",1,75);

%a("F+",1,150);

%a("D+",1,225);

%a("A+",1,75);

%a("G",1,300);

%a("G",2,150);

%a("G",1,225);

%a("G",1,75);

%a("G",2,150);

%a("F+",2,225);

%a("F",2,75);

%a("E",2,75);

%a("D+",2,75);

%a("E",2,150);

%a("G+",1,75);

%a("C+",2,150);

%a("C",2,225);

%a("B",1,75);

%a("A+",1,75);

%a("A",1,75);

%a("A+",1,150);

%a("D+",1,75);

%a("F+",1,150);

%a("A+",1,75);

%a("G",1,225);

%a("A+",1,75);

%a("D",2,300);

%a("G",2,150);

%a("G",1,225);

%a("G",1,75);

%a("G",2,150);

%a("F+",1,225);

%a("F",2,75);

%a("E",2,75);

%a("D+",2,75);

%a("E",2,150);

%a("G+",1,75);

%a("C+",2,150);

%a("C",2,225);

%a("B",1,75);

%a("A+",1,75);

%a("A",1,75);

%a("A+",1,150);

%a("D+",1,75);

%a("F",1,150);

%a("D+",1,225);

%a("A+",1,75);

%a("G",1,150);

%a("D+",1,225);

%a("A+",1,75);

%a("G",1,300);

%MEND;


推薦閱讀:

TAG:信息技術IT | 統計學 | SAS | R編程語言 |