12月 102008
 

Happy hearts and happy faces,
Happy play in grassy places–
-Good and Bad Children by Robert Louis Stevenson

I read this verse in W. Bennentt’s popular book, The Book of Virtues, during the bus-to-company time this morning. It’s interesting to read Stevenson’s Treasure Island, of course in Chinese edition when I was young.

Yes, it sounds “uncool”, –I went to work, with technical documents in my bag, and read a for-children book. A grown-up with childlike innocence? dare not say. I just read the book to fresh my mind and my English.

It snows little Beijing.

12月 102008
 

I just wanted to quickly introduce myself as the SAS R&D manager for SAS Text Miner. With my research-oriented background, I will be posting distinctly different types of blog entries than you will see from Manya, Barry and Mary.

I will be looking at detailed technical approaches and algorithms being researched for handling text data, i.e. the grungy details. So if you are more interested in a bird's eye view, you may want to skim over my postings. On the other hand, if you want to understand how things work, why we've decided to take the approach that we do, and what we are considering doing for the future, then tune right in. And I encourage you to make comments and suggestions. I am not tied to particular approaches, and I would love to find out "better" ways to do things that we may not even have considered.

Particular areas that I will be blogging about in the coming months include:
Continue reading "My wisdom (and lack thereof)"
12月 062008
 

Do you remember the old Faberge shampoo marketing campaign? "I told two friends about Faberge shampoo and they told two friends and so on and so on and so on ... " The one with the great visual to highlight viral marketing?

The onslaught of blogs and social media sites has initiated a huge power shift INTO the hands of customers. This can be good (if your customer is singing your praises), bad (if they are not), or more likely both.

The reality is that this represents a huge opportunity for businesses to use all available data in decision making to help you understand not only what your customers look like, but what they think. During a downturn in any economy, the customer is the last bastion, THE touch point to help you better understand what they think about your products and services.

Text mining is the technology that integrates structured and unstructured data to help you better understand your customers, enabling you to surpass the competition, save time and save money. While blogs and social media sites put power into customers’ hands, they also can empower businesses. Consider the JetBlue fiasco, which generated outrage across the Internet . The JetBlue CEO publicly apologized via YouTube! Since then, some 338,000 YouTube users have viewed the apology. They gave David Neeleman four stars for his performance. What also came out of this media was the opportunity to mine additional information – customer comments in response to the YouTube apology about the flight cancellations and peer ratings about those comments. All the makings of a “goldmine” for text and data mining for decision making. Current manual processes are inconsistent, costly and time-consuming, with information typically organized by functional area, not across the enterprise. Decisions get made in isolation. It's clear that companies must have automated processes to mine data to consistently to identify and quantify customer/product issues. Text mining is that technology. Businesses are rapidly embracing this technology. Are you one of them?
12月 042008
 
To take yesterday’s quote from a social media friend – “we live in a world of unlimited ideas”.  When it comes to analyzing text this quote would probably have to be my mantra. Analyzing text itself isn’t exactly a new idea.Government agencies have been doing this behind closed doors for a long time. What’s new is the ability to understand textual information while NOT being behind closed doors. Text mining/text analytics technology is available for commercial businesses to understand data about their customers, their competitors and much more. We use text for analysis, and combine related numeric fields. But even numbers can be saved as text strings and voice signals can be translated to text and used for better understanding of information. Imagine a bullet pushing the sound barrier. That’s what I picture when I think of The Text Frontier. We like to push boundaries – hard. And we’d like to share our experiences with you. We encourage you to join us pushing boundaries while sharing your experiences, or just watch us and comment. Whether you watch, wait or dive in with your thoughts, here’s something for you to think about:
2 + 2 = 4, but
two + 2 > 4
11月 182008
 
Treasures and memories and trash is what I found in my closet during a much needed cleaning. This was one of those deep cleans that only happens once every few years. I looked in every box, bag, and dark corner. You wouldn't believe the things I found -- treasures, memories, and trash. During one archeological dig into a plastic storage bag, I found a purse that had been long forgotten. As I am preparing it for the charity pile, I noticed a brilliant blue corner of cloth peeking out from inside the purse. I found this:

I do windows T-shirt
Do you recognize it? It is a SAS T-shirt from the early 90s. I got this shirt shortly after coming to work for SAS. (I'm guessing that it was about the time we released SAS 6.08.) Running SAS on Windows was new and exiting in the early 90s and this was a hot shirt. Finding this pristine, never-worn T-shirt started me to thinking. I can't be the only person with old SAS memorabilia stashed in a closet or drawer.

This post from Tom Hide on SAS-L assures me that I am not the only person keeping stuff. Tom has a copy of Guide to Using SAS 76. I've only seen pictures of manuals this old. See the pictures at the end of this post for a glimpse of old manuals as well as some other items from the past.



Do you have the oldest item or the most unique?


Let's have a little fun with our old stuff. What do you have? Is it old, funny, or cherished? Is it from a user group conference or from SAS? Tell us about it by writing a comment on this post. Show it to us by posting a link to a picture in your comment or by uploading pictures of your items to the sasmemories group on Flickr. If you just want to see the pictures from others, join the Flickr group at www.flickr.com/groups/sasmemories.
Continue reading "Treasures and Memories and Trash"
11月 142008
 
As you prepare your 2009 travel and education budgets, keep SAS Global Forum 2009 in mind. This conference is a great way to share and expand your existing SAS knowledge. The Gaylord National Resort in National Harbor will be over-run with SAS professionals from around the world. You can

  • meet the authors of your favorite conference paper
  • discover a new favorite paper
  • chat with SAS Technical Support staff, SAS R&D staff, and other SAS users.

Wait, there's more. The conference offers

If you are as excited about SAS Global Forum 2009 as I am, here's some information that you need to know.

SAS Global Forum registration and housing is now open. Take advantage of registering online for prompt confirmation reply and payment processes. Visit the home page at www.sasglobalforum.com and click REGISTER NOW.

The online registration system has a number of features that we hope you will find helpful. Those features include:

  • The ability to connect directly to hotel reservations at the end of your registration
  • The ability to log back into the system to review or modify your registration and hotel
  • Separate meal selections for each guest

If you have questions while registering or you are just wondering what else SAS Global Forum has to offer, look for the Chat Now option on the right side of most of our conference pages.

SAS Global Forum has reserved rooms at discounted group rates for conference attendees at hotels in the National Harbor, Maryland, and Alexandria, Virginia, areas. Reservations must be made by booking online.
11月 102008
 
原文載點:http://www.nesug.info/Proceedings/nesug06/dm/da30.pdf這是一篇教導如何使用 data step 和 proc sql 合併和分割資料的 SAS 技術文件,由 Emmy Pahmer 於 NESUG 2006 發表。本文所使用的範例如下:你拍攝的 2008-11-03_1353。這筆資料總共只有五個觀測值,每個觀測值包含三個變數:年齡、姓名和性別。其中第五個觀測值的性別是打錯的 G。。分割資料若想要將上述資料依照性別切割成兩個分開的資料集,則有下列幾種方式。1. 使用兩個 data step:這是最笨但也是最直接的方式。程式碼如下所示:
data males;    set everyone;    if sex = 'M';run;data females;    set everyone;    if sex = 'F';run;
2. 使用兩個 data step 配合 where:這個方法僅僅是縮短程式碼行數。程式碼如下:
data female;    set everyone (where=(sex=’F’)) ;run;data male;    set everyone (where=(sex=’M’)) ;run;
有此程式可知,這只是把 IF 的指令改成 WHERE 並放在 SET 後面。對行數來說,的確是減少了,不過打的字變多了,因為 WHERE 後面的條件式要加上括弧。3. 使用兩個 data step 配合 where:這個方法僅僅是把 WHERE 從 SET 移到 DATA 後面,並沒有太特別的地方。程式碼如下:
data female (where= (sex = ‘F’)) ;    set everyone ;run;data male (where= (sex = ‘M’)) ;    set everyone ;run;
4. 使用一個 data step 並配合 IF...ELSE... 和 OUTPUT:這是比較進階的方式,可以大幅縮短程式碼的行數。如下所示:
data males females;    set everyone;    if sex = 'F' then output females;    else if sex = 'M' then output males;run;
由於本資料中某觀測值的性別是打錯的。為了確定有沒有這類的情況,當資料相當龐大時,建議使用下列程式碼:
data males females;    set everyone;    if sex = 'F' then output females;        else if sex = 'M' then output males;            else put “Neither F nor M - check “ _all_; *or output to another dataset ;run;
其中紅色那行的程式碼會讓性別變數不是 F 和 M 的觀測值通通分類到 _all_ 這個資料集中。亦或是另外定義一個資料集把他們 output 進去。當打開這個資料集時,如果裡面是空的,就可以確定沒有打錯的情況產生。5. 使用一個 data step 並配合 WHERE:這是從方法二改良來。程式碼如下:
data female (where=(sex=’F’)) male (where=(sex=’M’)) ;    set everyone ;run;
這個程式碼比方法四 要來的更精簡精簡。如果想要擁有方法三第二個可以偵測有沒有打錯的資料,則可以改進如下:
data female (where=(sex=’F’)) male (where=(sex=’M’)) checkothers (where = (sex not in (‘M’,’F’))) ;    set everyone ;run;
道理同方法四,把 sex 不是 M 和 F 的通通丟到 checkothers 這個資料集裡面,然後再去看看該資料集是不是空的。6. 使用 proc sql:使用 proc sql 看起來好像比較高檔,但是行數並沒有減少。
proc sql;    create table males as    select *    from everyone (where=(sex='M'));    create table females as    select *    from everyone (where=(sex='F'));quit;
7. 使用一個 data step 把 不同的變數放到不同的資料集:若想要把 who 和 age 放到新資料集 age,然後再把 who 和 sex 放到新資料集 sex,則可仿照方法五來切割。程式如下:
data age (keep = who age) sex (keep = who sex);    set everyone;run;
8. 使用 proc sql 完成方法七:程式如下:
proc sql;    create table age as    select who, age    from everyone;    create table sex as    select who, sex    from everyone;quit;
感覺行數沒有減少很多,只是寫法比較接近口語。。合併資料這回使用兩筆資料,如下所示:你拍攝的 2008-11-03_1421。其中 EVERYONE 這筆和之前用的一樣,而新的 ACTIVITY 資料有一點要特別注意的是它並沒有排序過。為什麼要特別強調這一點,理由是在 SAS 的合併過程中,一定要設定一個 index variable,這樣 SAS 才有辦法依照那個 index variable 來進行資料合併。而那個被設定成 index variable 的變數一定要經過排序,否則 SAS 在合併的過程中會錯亂掉。這個錯亂有時候還是會給你 output,只是結果是錯的。如果一時忽略沒有看到 log 視窗上面的警告訊息,就完蛋了。因此若要依照「who」這個變數來合併這兩組資料,則必須要先用 PROC SORT 把該變數排序:
proc sort data=activity;    by who;run;
而通常要養成一個好習慣就是所有合併的資料最好都給他排序一下,免得有漏網之魚。反正 PROC SORT 的程式碼很簡單,多寫幾行比較安心:
proc sort data=everyone;    by who;run;
然後用 merge 和 by 來合併:
data combined_11;    merge everyone activity;    by who;run;
結果如下:你拍攝的 2008-11-03_1427。從上表得知,Annie, Bill, Chandra, Igor, Jose 和 Karen 在 ACTIVITY 裡面有資料,所以合併時會顯示在 activity 這個變數底下,但 David 和 Eleanor 則沒有出現在 ACTIVITY 裡面,所以合併後他們兩人的 activity 變數就變成 missing data 了。Age 也是同樣的道理。如果只想顯示同時出現在兩個資料的觀測值,則必須啟用 in 這個指令。程式碼如下:
data combined_12;    merge everyone (in = in_a) activity (in = in_b);    by who;    if in_a and in_b;run;
使用 in 這個指令會讓 SAS 在合併的過程中,於兩組資料裡面各加上一個隱藏的變數,分別名為 in_a 和 in_b,其數值都預設為 1。合併之後在程式裡面加上「if in_a and in_b;」來讓 SAS 挑出同時具有 in_a=1 和 in_b=1 的觀測值(要打成「if in_a=1 and in_b=1;」也可以),缺少任一個變數的觀測值則會自動被剔除。結果如下:你拍攝的 2008-11-03_1433。如果想要知道哪些觀測值被剔除,可使用下列程式碼:
data combined_14;    merge everyone (in = in_a) activity (in = in_b);    by who;    if in_a and in_b then output;        else if in_a then put "In A only: " Who=; *or output to another dataset ;            else if in_b then put "In B only: " Who=;run;
最後那兩個 else if... 會讓程式在 log 視窗印出下列字樣:你拍攝的 2008-11-03_1437。同樣地,proc sql 也可達成同樣效果:
proc sql;    create table combined_15a as    select a.*, b.activity, b.sex    from everyone as a, activity as b    where a.who = b.who    order by activity    ;quit;
或者
proc sql;    create table combine_15b as    select a.*, b.activity, b.sex    from everyone as a inner join activity as b    on a.who = b.who    ;quit;
但由於 proc sql 的指令比較麻煩,所以還是建議使用 data step 來完成。CONTACT INFORMATIONYour comments and questions are valued and encouraged. Contact the author at:Emmy PahmerMDS Pharma ServicesSt. Laurent, QuébecWork Phone: (514) 333-0042 ext. 4222E-mail: emmy.pahmer@mdsinc.com
11月 072008
 
SAS Press wants you to get to know your favorite SAS authors, so they are taping interviews with authors and making them available to you as podcasts. One of the very first podcasts was with Chris Hemedinger, co-author of SAS for Dummies.

One of the most recent podcasts is with Ron Cody, who is the author of seven SAS books, the first of which was published in 1985. His Learning SAS® by Example: A Programmer’s Guide is one of SAS’ best selling titles. Listen to this podcast to find out more about the quiet life of this popular SAS author.

In between Chris and Ron, we have interviewed Michael Raithel, Art Carpenter, Phil Mason, Howard Schreier, and many more. To hear Ron and the other authors talk about SAS, their reasons for writing the books that you love, and their writing process, visit the SAS Press podcasts page on support.sas.com.

Let us know what you think
We created a quick poll to gather a little information about how you use podcasts. Please take a minute to visit the poll in the right column of this page and tell us what you think.
11月 012008
 
原文載點:http://www2.sas.com/proceedings/forum2007/099-2007.pdf

SAS 的 ODS 系統通常是拿來把報表另存成新的資料或者是列印出比較精緻的格式出來。但大多數的人可能不知道 ODS 還可以像 Word 一樣編輯報表,舉凡加上顏色、字型粗細大小、甚至是上標下標、放特殊符號,通通可以在 ODS 裡面完成。Cynthia L. Zender 於 SAS Global Forum 2007 發表的技術文件教導使用者如何來完成這些動作。

在決定使用 ODS 來編輯文件時,必須先宣告要使用哪種特殊符號來命令 ODS 開始進行一些動作。這個宣告得用 ods escapechar 來完成。比方:
ods escapechar='^';
ods escapechar='~';
ods escapechar='#';
接下來的範例接使用「^」符號來命令 ODS 編輯文件。

範例一:編輯文字

一個很簡單例子。假設要列印出某個字串變數,資料如下所示:
data use_esc;
length var1 $200;
var1 = "The quick brown fox";
output;
run;
ods html;
proc print data=use_esc;
run;
ods html close;

則 ODS 只會印出下面這種相當單調的結果:
你拍攝的 2008-10-24_1546。
下面的程式將可改變字體的粗細、字型和字的顏色:
data use_esc;
length var1 $200;
var1 = "The quick brown fox";
output;
var1 = "The ^S={font_weight=bold}quick ^S={} brown fox";
output;
var1 = "The quick ^S={foreground=brown}brown ^S={}fox";
output;
var1 = "The quick brown ^S={font_face='Courier New'}fox ^S={}";
output;
var1 = "The ^S={font_weight=bold}quick ^S={}" ||
"^S={foreground=brown}brown ^S={}"||
"^S={font_face='Courier New'}fox ^S={}";
output;
run;
ods html style=sasweb;
ods escapechar='^';
proc print data=use_esc;
run;
ods html close;

首先,在原先的 data step 裡面加上紅色部分的程式碼。其中,「^」就是用來宣告之後的 ODS 要進行某些動作。S={} 即是用來編輯。以第一個紅色程式碼來看,^S={font_weight=bold} 接在 quick 前面即是要讓 quick 變成粗體的 quick。第二個紅色程式碼 ^S={foreground=brown} 是將 brown 的顏色變更為棕色的 brown。第三個紅色程式碼 ^S={font_face='Courier New'} 即是變更 fox 的字型為 Courier New 的 fox。所有的動作完成後都必須要在後面加上 ^S={},ODS 才會停止編輯。如果沒有 ^S={} 來中斷,則之前所宣告的編輯動作將會繼續套用在後面的內容中。第四個紅色程式碼比較複雜,這是將前三個紅色程式碼合併。此處將 quick, brown 和 fox 拆成三段,編輯過後用連接符號「||」將結果串起來。但根據我自己試驗的結果,不需要那麼麻煩,直接寫成下列的程式碼也可以做出同樣的效果:
var1 = "The ^S={font_weight=bold}quick ^S={} ^S={foreground=brown}brown ^S={} ^S={font_face='Courier New'}fox ^S={}";
最後,在宣告 ods html 之後,不要忘了加上 ods escapechar='^' 來讓 ODS 知道之前使用的「^」符號是要叫 ODS 做一些編輯動作。

執行後的結果如下所示:
你拍攝的 2008-10-24_1559。

範例二:加上特殊符號

特殊符號的通常用在數學方程式、註解、或化學式裡面。而使用方式也不像編輯文字一樣要用 ^S={options} 來宣告,而只要用 ^={options} 即可。假設想要做出下面這種表格:


則可使用下列程式:
data sup_sub;
length myvar $200;
myvar = "Pythagorean Theorem: a^{super 2} + b^{super 2} = c^{super 2}";
output;
myvar = "This is something that needs a footnote. ^{super 1}";
output;
myvar = "Macbeth: 'Is this a dagger I see before me?' ^{dagger}";
output;
myvar = "The Caffeine molecule is an alkaloid of the methylxanthine family: " ||
"C^{sub 8}H^{sub 10}N^{sub 4}O^{sub 2}";
output;
run;
ods html file='inline2.html' style=sasweb;
ods rtf file='inline2.rtf' notoc_data;
ods pdf file='inline2.pdf';
ods escapechar='^';
proc print data=sup_sub;
title j=r 'PDF & RTF: Page ^{thispage} of ^{lastpage}';
title2 j=c 'RTF only: ^{pageof}';
footnote '^{super 1}If this were a real footnote, there would be something very academic here.';
footnote2 '^{dagger} Macbeth talked to himself a lot. This quote is from Macbeth: Act 2, Scene 1, Lines 33-39.';
run;
ods _all_ close;


在第一個紅色程式碼中,畢氏定理需要在 a, b, c 各上標一個「2」,這個動作用 ^{super 2} 即可完成。換句話說,super 這個指令在 ^{} 裡面就是拿來做上標用的。第二個紅色程式碼同樣也是要將最後的 1 給上標,所以使用 ^{super 1} 來完成。第三個紅色程式碼同樣也是要加上一個特殊符號當作註解符號。而這個小小的十字架需要使用 ^{dagger} 才能呼叫出來。第四個紅色程式碼是要編輯一個化學方程式,讓一些數字在英文字旁邊坐下標,所以這個動作就得用 ^{sub n} 來完成。接著看最後 proc print 裡面的紅色程式碼。裡面用兩個 title 指令和 footnote 指令來完成表格標題和註解的動作。其中,在 title 裡面,^{thispage} 和 ^{lastpage} 只會作用於 ods rtf 或 ods pdf 裡面。這兩個指令會自動將整份文件的頁數已經該頁是屬於第幾頁列印出來。但這個功能在 ods html 顯示不出來。所以 ^{thispage} 和 ^{lastpage} 在 html 報表裡面會變成空白。同樣地,title2 是讓標題顯示這屬於整份文件的第幾頁,使用 ^{pageof} 來執行。可是這個指令只能在 rtf 文件裡面才會有作用,在 pdf 裡面將會把 ^{pageof} 原封不動地印出來,但在 html 文件裡面則會變成空白。

這是 rtf 文件的結果:

這是 pdf 文件的結果:


範例三:折行

如果一串文字太常,如上例的第四個化學方程式,則可使用折行的指令來讓字串在某處斷行。這個動作只要簡單地在宣告符號後面加上個「n」或「an」(a=任意數字)即可。程式如下:
data linebr;
length myvar $200;
myvar ="The Caffeine molecule is an alkaloid of the methylxanthine family: ~n" ||
" C~{sub 8}H~{sub 10}N~{sub 4}O~{sub 2}";
output;
myvar ="The Caffeine molecule is an alkaloid of the methylxanthine family: ~2n" ||
" C~{sub 8}H~{sub 10}N~{sub 4}O~{sub 2}";
output;
myvar ="The Caffeine molecule is an alkaloid of the methylxanthine family: ~3n" ||
" C~{sub 8}H~{sub 10}N~{sub 4}O~{sub 2}";
output;
myvar ="The Caffeine molecule is an alkaloid of the methylxanthine family: ~4n" ||
" C~{sub 8}H~{sub 10}N~{sub 4}O~{sub 2}";
output;
run;
ods listing;
ods html file='inline3.html' style=sasweb;
ods rtf file='inline3.rtf' notoc_data;
ods pdf file='inline3.pdf';
ods escapechar='~';
proc print data=linebr;
title 'Using the ODS ESCAPECHAR for line break';
title2 'Title 2';
title3 'Title 3';
title4 'Title 4';
title5 'Title 5';
title6 'Title 6';
title7 'Title 7';
title8 'Title 8';
title9 'Title 9';
title10 'Title 10 ~n Title 11 ~n Title 12 ~n Title 13 ~n Title 14';
run;
ods _all_ close;

為了與前兩例做一點區別,此例將宣告符號「^」改成「~」。在 data step 裡面,分別將 The Caffeine molecule is an alkaloid of the methylxanthine family: 和 化學方程式之間各斷一、二、三、四行,因此只要在冒號後面打上「~n」,「~2n」,「~3n」,「~4n」即可。設定完後不要忘了在 proc print 前面加上 ods escapecha='~'; ,否則之前的宣告不會被執行。至於下面很多 title 指令是要展示折行的效果。如果不使用折行,折需要連續呼叫 titlen statement。但有了折行指令,則只需要打一行,裡面再連續使用數個 ~n 即可(如最後的紅色程式碼所示)。僅列出 html 的結果如下:
你拍攝的 2008-10-24_1641。

例四:更改欄位設定

以 ods html 來說,如果沒有特別的設定,則一般的輸出報表會像下圖所示:
你拍攝的 2008-10-24_1645。

如果想要將整行從第一個 Sales 處斷行,並把 Sales Total Sales 改成斜體的話,可使用下列程式碼:
ods html style=sasweb;
ods escapechar='^';
proc means data=sashelp.shoes sum min mean max;
class Region;
var Sales;
label Sales='^S={font_style=italic}^nShoe Sales';
run;
ods html close;

紅色部分就是用來更改那個表格內標籤的設定。^S={font_style=italic} 是用來將後面的 Total Sales 改成斜體字。而緊接著的 ^n 就是用來斷行的。結果如下:
你拍攝的 2008-10-24_1654。

範例五:特殊符號

有些特殊符號需要使用特定的指令來印出。承上例,我們想要在表格後面加上註腳,並打上 trade mark、copy right mark 和美分符號,程式如下:
data _null_;
hexcode = 'AE'x;
call symput ('hexreg',hexcode);
hexcode1 = 'A9'x;
call symput('hexcopy' , hexcode1);
hexcode2 = 'A2'x;
call symput('hexcent', hexcode2);
run;
** Display the hex codes in the SAS log;
%put hexreg= &hexreg;
%put hexcopy= &hexcopy;
%put hexcent= &hexcent;
ods html file='inline5.html' style=sasweb;
ods rtf file='inline5.rtf' notoc_data startpage=no;
ods pdf file='inline5.pdf' startpage=no;
ods escapechar='^';
ods noptitle;
proc means data=sashelp.shoes sum min mean max;
class Region;
var Sales;
label Sales='^S={font_style=italic}^nShoe Sales';
run;
ods pdf text="^S={just=c font_size=18pt}PDF File^nOpens with Adobe Reader^n
&hexreg &hexcopy My 2&hexcent";
ods rtf text="^S={just=c font_size=18pt}RTF File^nOpens with Microsoft Word^n
&hexreg &hexcopy My 2&hexcent";
ods html text="^S={just=c font_size=18pt}HTML File^nOpens with Microsoft Internet
Explorer^n &hexreg &hexcopy My 2&hexcent";
proc freq data=sashelp.shoes;
tables Product /nocum;
label Product='^S={font_style=italic}Shoe Types Sold';
run;
ods _all_ close;

使用者必須先用一個 _null_ 的 data step,呼叫 %symput 函式把這三個特殊符號叫進來。這三個特殊符號在 SAS 系統裡都有自己的代稱,trade mark 的代碼是 'AE'x,copy right mark 的代碼是 'A9'x,而美分的代碼是 'A2'x。然後用 %put 指令把剛剛用 %symput 叫進來的三個代碼設定為巨集參數,供之後使用。而那些註解可以直接寫在 ods 後面,使用 text 來印出,而所有諸如編輯文字、斷行以及安插特殊符號的指令全部都可以在 text 後面使用。以 ods html 來講, ^S={just=c font_size=18pt} 即是設定整個註腳的字型大小為 18pt,並且全部置中。放在 File 和 Opens 中間的 ^n 即表示從這個位置斷行,最後使用 &hexreg、&hexcopy 和 &hexcent 把 trade mark, copy right mark 和美分符號安插進去。結果如下:
你拍攝的 2008-10-24_1702。

範例六:安插圖片

ODS 也可以拿來安插圖片。先看看程式:
proc format;
value $prdimg 'Boot' = 'c:\temp\boot.jpg'
"Women's Dress" = 'c:\temp\dressheels.jpg'
'Slipper' = 'c:\temp\slipper.jpg';
run;
ods html file='inline6.html' style=sasweb;
ods rtf file='inline6.rtf' notoc_data;
ods pdf file='inline6.pdf';
ods escapechar='^';
proc report data=sashelp.shoes nowd style(column) = {vjust=b};
title '^S={preimage="c:\temp\shoe_logo.jpg"}';
where product in ('Boot', 'Slipper', "Women's Dress");
column Product Sales N;
define Product / group
style(header)={background=white foreground=black}
style(column)={postimage=$prdimg.};
define Sales / sum;
define N / '^S={background=white foreground=black}Number of Sales';
run;
ods _all_ close;

如果只要在 title 上安插圖形的話,則可簡單地於 title statement 後面加上 ^S={preimage="路徑\檔名.jpg"} 來把圖形放上。如果要在文件內容部分的話,得需要先用 proc format 把每一張圖的路徑和檔名分別設定給某個變數的不同的 value,並用一個 $prdimg 來表示(這個字串可以自行設定)。然後在 proc report 裡面的 define 後面放上選項 style(column)={postimage=prdimg.},則每一欄裡面都會安插不同的圖形。若只想單純的更改欄位背景或前景顏色的話,則使用 ^S={backgroun=color1 foreground=color2} 來改變。此例使用 ^S={background=white foreground=black} 把總數欄位的前景顏色改成黑色,背景顏色改成白色。

三種輸出格式的結果如下:
你拍攝的 2008-10-24_1708。

CONTACT INFORMATION
Your comments and questions are valued and encouraged. Contact the author:
Cynthia L. Zender
SAS Institute Inc.
Home Office
Las Cruces, NM 88011
Work Phone: (505) 522-3803
Fax: (505) 521-9328
E-mail: Cynthia.Zender@sas.com
 Posted by at 1:17 下午
10月 312008
 
For those of you not living in the southeast, it's cold here this week. So cold that I scrambled over to the Web site of a local TV station to find out if we were in for a hard frost. In addition to the weather forecast, I was pleasantly surprised to see the site was highlighting a couple of interviews with SAS CEO and founder Jim Goodnight. I made a note to return later to capture the URLs so that I could share them with you.

In three interviews in The Skinny, a blog on WRAL's LocalTechWire.com, Dr. Goodnight shares his thoughts on where SAS is headed, retirement, and the stock market.

You can also watch the video of the interview that produced most of these articles.



Updated Nov. 19, 2008: If you are looking for more insight from Dr. Goodnight, read this arcticle in Business Week where he comments on the economy, education, and the bailout.