SAS編程-Table:層級(jí)關(guān)系的頻數(shù)匯總處理 ——層級(jí)拼接法

臨床試驗(yàn)TFL輸出中,有一類頻數(shù)匯總表的各條目是包含層級(jí)關(guān)系的。例如,之前介紹的SAS編程:按SOC和PT類別匯總AE的受試者發(fā)生率躺盛,單個(gè)SOC下,可能會(huì)對(duì)應(yīng)多個(gè)PT咙鞍。

對(duì)于具有層級(jí)關(guān)系的頻數(shù)匯總表房官,常規(guī)的處理方式是,先對(duì)各個(gè)層級(jí)進(jìn)行單獨(dú)統(tǒng)計(jì)续滋,之后再匯總進(jìn)行排序翰守,前面提到的AE SOCPT表格就是這樣處理的。

今天疲酌,介紹另一種方法蜡峰,我給這種方法取名為層級(jí)拼接法層級(jí)拼接法的本質(zhì)是朗恳,將多層級(jí)轉(zhuǎn)化為單層級(jí)進(jìn)行處理湿颅。這個(gè)方法的效率要比各個(gè)層級(jí)單獨(dú)處理高很多,推薦大家嘗試使用粥诫。

層級(jí)拼接的處理主要在文章3.3油航、3.5、3.6部分怀浆,結(jié)合代碼和輸出結(jié)果谊囚,希望讀者能夠掌握這樣的處理方法

1. 層級(jí)處理介紹

看過我前面介紹受試者處置頻數(shù)匯總的讀者执赡,應(yīng)該有印象镰踏。頻數(shù)匯總中,各條目對(duì)應(yīng)不同的變量條件的情況沙合,是很常見的奠伪。對(duì)應(yīng)的處理方法,無外乎單條目條件處理后匯總首懈,或者各條目條件合并為一個(gè)變量控制绊率,統(tǒng)一處理

具有層級(jí)關(guān)系的頻數(shù)表究履,跟之前介紹的匯總表有2點(diǎn)不同滤否。第一,層級(jí)關(guān)系的條目數(shù)量由具體數(shù)據(jù)確認(rèn)挎袜,沒有事先指定;第二肥惭,層級(jí)關(guān)系的條目需按所要求的順序排序盯仪。

基于此,將多層級(jí)轉(zhuǎn)化為單層級(jí)時(shí)蜜葱,需要保留各層級(jí)信息全景,方便后續(xù)排序。

臨床試驗(yàn)TFL中牵囤,常見的具有層級(jí)關(guān)系的內(nèi)容有爸黄,地區(qū)國(guó)家滞伟、AE SOCPT的頻數(shù)匯總。

這篇介紹炕贵,國(guó)家地區(qū)匯總表的層級(jí)拼接處理梆奈,后續(xù)介紹AE SOCPT的層級(jí)處理。

2. 具體示例

示例

這是一個(gè)涉及多個(gè)地區(qū)称开、國(guó)家的多中心1期試驗(yàn)亩钟,這張Table需要匯總Region、Country鳖轰、Site的信息清酥。

這些信息保存在ADSL中,Site信息由兩個(gè)變量拼接而成蕴侣,這里看成一個(gè)變量進(jìn)行處理焰轻。

這三個(gè)變量中“范圍”最小的是Site,一個(gè)Site有對(duì)應(yīng)的Country昆雀,一個(gè)Country有對(duì)應(yīng)的Region辱志。一行記錄有對(duì)應(yīng)3個(gè)變量的信息,每個(gè)變量信息都會(huì)被計(jì)數(shù)忆肾,也就是說一行記錄會(huì)被計(jì)數(shù)3次荸频。

這樣的“重復(fù)計(jì)數(shù)”,可以通過兩種方式實(shí)現(xiàn):第一客冈,計(jì)數(shù)3次旭从,每次計(jì)數(shù)不同的變量;第二场仲,將記錄拆分成3條和悦,一次計(jì)數(shù)3個(gè)變量的信息

層次拼接法渠缕,就是采取第二種方式鸽素,拆分時(shí),通過變量拼接亦鳞,保留對(duì)應(yīng)的層級(jí)關(guān)系馍忽。

3. SAS代碼演示

首先,附上我的QC“5段論”:

***1. Create formats for output;
***2. Get data for analysis;
***3. Calculate statistics;
***4. Create dataset for QC;
***5. Compare;

3.1 匯總組的設(shè)置

這是一個(gè)Ongoing的1期劑量擴(kuò)大試驗(yàn)燕差,計(jì)劃有6個(gè)試驗(yàn)組遭笋,目前數(shù)據(jù)中只有前4個(gè)試驗(yàn)組的信息。缺失組別的內(nèi)容徒探,我會(huì)使用Means過程步中的preloadfmt選項(xiàng)補(bǔ)充缺失組別的信息瓦呼,具體參考SAS編程:頻數(shù)匯總時(shí)如何處理分析分組種類不全的情況?测暗。

Shell中要求這張Table有匯總組(Total)央串,這個(gè)我會(huì)采用Format過程步中multilabel選項(xiàng)進(jìn)行實(shí)現(xiàn)磨澡,具體內(nèi)容可以參考SAS編程:生成Table時(shí),匯總組(Total)組如何處理质和?稳摄。

基于上面兩點(diǎn)考慮,部分Format可以這樣設(shè)置:

***1. Craete Formats for output;
proc format;
  value trt01pn(notsorted multilabel)
    1 = 1
    2 = 2
    3 = 3
    4 = 4
    5 = 5
    6 = 6
    1-6 = 99 /*For total*/
  ;
run;
3.2 計(jì)算BigN的人群獲取
***2. Get data for analysis;

**2,1 Get data for BigN;
data adsl;
  set adam.adsl;
  where fasfl = "Y";

  *Flag for count;
  flag = 1;

 length site $50;
 site = catx("/", siteidss, invnam);
run;
3.3 計(jì)算小n的人群獲取——層級(jí)拼接
**2.2 Get data for small n;
data adsl_n;
  set adsl;
  
  length cat $200;
  
  cat = strip(geogr1); output;
  cat = strip(geogr1)||"!"||strip(propcase(countryl)); output;
  cat = strip(geogr1)||"!"||strip(propcase(countryl))||"!"||strip(site); output;

  proc sort;
    by cat;
run;

第2部分提到侦另,一條記錄的3類信息會(huì)被計(jì)數(shù) (Region秩命、Country、Site)褒傅,利用Output語(yǔ)句將1條記錄輸出為3條弃锐,每一條對(duì)應(yīng)需要計(jì)數(shù)的那一類信息。拆分時(shí)殿托,各變量以感嘆號(hào)!分隔霹菊,這樣可以通過感嘆號(hào)的數(shù)目來判斷所屬具體層級(jí)。

排序變量是新建的cat變量支竹,其實(shí)這就相當(dāng)于按照by geogr1 countryl site進(jìn)行排序旋廷。因?yàn)锳DSL數(shù)據(jù)集本身是Subject Level,1個(gè)受試者1條記錄礼搁,所以計(jì)算頻率時(shí)饶碘,數(shù)據(jù)集是不需要去重的

3.4 計(jì)算BigN

處理好分析數(shù)據(jù)后馒吴,BigN的計(jì)算與之前的文章一樣:

***3. Calculate statistics;

**3.1 Derive BigN and save them to macro vars; 
proc means data =adsl nway completetypes;
  format trt01pn trt01pn.;
  class trt01pn / preloadfmt mlf order = data; 
  var flag;
  output n = bign nmiss = nmiss out = BigN; 
run;

data _null_;
  set BigN;
  call symputx("N_"||strip(trt01pn), put(bign,best.)); 
run;

data check_bign;
  set sashelp.vmacro;
  where index(name, "N_") and length(name)<=6;
  keep name value; 
run;
3.5 計(jì)算小n

小n的計(jì)算也與之前文章大體類似扎运,只是不需要為分析變量cat提前設(shè)置Format。

**3.2 Calculate small n and percentage;

*Get small n;
proc means data = adsl_n nway completetypes;
  format trt01pn trt01pn.;
  class trt01pn / preloadfmt mlf order = data;

  class cat;

  var flag;
  output n = count nmiss = nmiss out = count1; 
run;

*Get percentage; 
data count2;
  merge count1 bign; 
  by trt01pn;
  length freq $200;
  if bign ne 0 then freq = strip(put(count,best.))||" ("||strip(put(count/bigN*100,8.1)) ||")";
  else freq = "0 (-)";

  proc sort;
    by cat trt01pn;
run;

*Transpose results;
proc transpose data = count2 out = count3 prefix= trt_ ;
  by cat; 
  var freq; 
  id trt01pn; 
run;

百分比處理完畢后饮戳,下面要對(duì)第一列的內(nèi)容進(jìn)行處理豪治。計(jì)數(shù)時(shí),是按拼接后的變量信息計(jì)數(shù)扯罐。計(jì)數(shù)完畢后负拟,需要根據(jù)所在層級(jí)輸出第一列的內(nèi)容。而所在層級(jí)的判斷歹河,是通過所含感嘆號(hào)數(shù)量進(jìn)行標(biāo)記掩浙。

data final1;
  set count3;

  length c1 - c8 $200;

  if count(cat, "!") = 0 then c1 = cat;
  else if count(cat, "!") = 1 then c1 = scan(cat, 2, "!");
  else if count(cat, "!") = 2 then c1 = scan(cat, 3, "!");

  c2 = trt_1;
  c3 = trt_2;
  c4 = trt_3;
  c5 = trt_4;
  c6 = trt_5;
  c7 = trt_6;
  c8 = trt_99;
  
  keep c:;

  proc sort;
    by cat;
run;

輸出結(jié)果如下,結(jié)果排序?yàn)楦鲗蛹?jí)字母排序秸歧,以下基本為完整的輸出內(nèi)容了厨姚。

Results
3.6 按匯總列頻數(shù)降序排序

具有層次關(guān)系的頻數(shù)匯總表,如果結(jié)果按字符排序寥茫,上面輸出就是最后的結(jié)果遣蚀。

但這類表通常需要按匯總組的頻數(shù)降序排列矾麻,頻數(shù)相同纱耻,按字符順序排序芭梯。這時(shí)候還需要對(duì)數(shù)據(jù)集進(jìn)一步處理,以達(dá)到排序的要求弄喘。

這一步玖喘,主要操作是為每一個(gè)層級(jí)附上對(duì)應(yīng)的匯總列頻數(shù),通過BY語(yǔ)句蘑志、Retain語(yǔ)句為組內(nèi)賦值實(shí)現(xiàn)累奈。

為3個(gè)層級(jí)新建對(duì)應(yīng)的分組變量 (cat1, cat2, cat3),并按層級(jí)分組排序

*Create group vars;
data final1;
  set count3;

  length c1 - c8 $200;

  if count(cat, "!") = 0 then c1 = cat;
  else if count(cat, "!") = 1 then c1 = scan(cat, 2, "!");
  else if count(cat, "!") = 2 then c1 = scan(cat, 3, "!");

  c2 = trt_1;
  c3 = trt_2;
  c4 = trt_3;
  c5 = trt_4;
  c6 = trt_5;
  c7 = trt_6;
  c8 = trt_99;

  *For freqency sort;
  num = input(scan(c8,1,"("), best.);

  cat1 = scan(cat, 1, "!");
  cat2 = scan(cat, 2, "!");
  cat3 = scan(cat, 3, "!");
  
  keep num c:;

  proc sort;
    by cat1 cat2 cat3;
run;

為每一分組賦上組內(nèi)匯總頻數(shù) (cat1n, cat2n, cat3n)急但,并以頻數(shù)降序澎媒、相同頻數(shù)以字母順序升序排列

*Get counts for the group vars;
data final2;
  set final1;
  by cat1 cat2 cat3;

  retain cat1n cat2n cat3n;

  if first.cat1 then cat1n = num;
  if first.cat2 then cat2n = num;
  if first.cat3 then cat3n = num;

  proc sort;
    by descending cat1n cat1 descending cat2n cat2 descending cat3n cat3;
run;

輸出結(jié)果如下:

Results 2

這個(gè)就是最后輸出結(jié)果的主體部分,結(jié)合cat1n, cat2n, cat3n的具體取值波桩,希望讀者能夠掌握頻數(shù)倒序排序的處理戒努。

4. 主體程序代碼匯總:

***1. Craete Formats for output;
proc format;
  value trt01pn(notsorted multilabel)
    1 = 1
    2 = 2
    3 = 3
    4 = 4
    5 = 5
    6 = 6
    1-6 = 99 /*For total*/
  ;
run;


***2. Get data for analysis;

**2,1 Get data for BigN;
data adsl;
  set adam.adsl;
  where fasfl = "Y";

  *Flag for count;
  flag = 1;

 length site $50;
 site = catx("/", siteidss, invnam);
run;

**2.2 Get data for small n;
data adsl_n;
  set adsl;
  
  length cat $200;
  
  cat = strip(geogr1); output;
  cat = strip(geogr1)||"!"||strip(propcase(countryl)); output;
  cat = strip(geogr1)||"!"||strip(propcase(countryl))||"!"||strip(site); output;

  proc sort;
    by cat;
run;


***3. Calculate statistics;

**3.1 Derive BigN and save them to macro vars; 
proc means data =adsl nway completetypes;
  format trt01pn trt01pn.;
  class trt01pn / preloadfmt mlf order = data; 
  var flag;
  output n = bign nmiss = nmiss out = BigN; 
run;

data _null_;
  set BigN;
  call symputx("N_"||strip(trt01pn), put(bign,best.)); 
run;

data check_bign;
  set sashelp.vmacro;
  where index(name, "N_") and length(name)<=6;
  keep name value; 
run;

**3.2 Calculate small n and percentage;

*Get small n;
proc means data = adsl_n nway completetypes;
  format trt01pn trt01pn.;
  class trt01pn / preloadfmt mlf order = data;

  class cat;

  var flag;
  output n = count nmiss = nmiss out = count1; 
run;

*Get percentage; 
data count2;
  merge count1 bign; 
  by trt01pn;
  length freq $200;
  if bign ne 0 then freq = strip(put(count,best.))||" ("||strip(put(count/bigN*100,8.1)) ||")";
  else freq = "0 (-)";

  proc sort;
    by cat trt01pn;
run;

*Transpose results;
proc transpose data = count2 out = count3 prefix= trt_ ;
  by cat; 
  var freq; 
  id trt01pn; 
run;

*Create group vars;
data final1;
  set count3;

  length c1 - c8 $200;

  if count(cat, "!") = 0 then c1 = cat;
  else if count(cat, "!") = 1 then c1 = scan(cat, 2, "!");
  else if count(cat, "!") = 2 then c1 = scan(cat, 3, "!");

  c2 = trt_1;
  c3 = trt_2;
  c4 = trt_3;
  c5 = trt_4;
  c6 = trt_5;
  c7 = trt_6;
  c8 = trt_99;

  *For freqency sort;
  num = input(scan(c8,1,"("), best.);

  cat1 = scan(cat, 1, "!");
  cat2 = scan(cat, 2, "!");
  cat3 = scan(cat, 3, "!");
  
  keep num c:;

  proc sort;
    by cat1 cat2 cat3;
run;

*Get counts for the group vars;
data final2;
  set final1;
  by cat1 cat2 cat3;

  retain cat1n cat2n cat3n;

  if first.cat1 then cat1n = num;
  if first.cat2 then cat2n = num;
  if first.cat3 then cat3n = num;

  proc sort;
    by descending cat1n cat1 descending cat2n cat2 descending cat3n cat3;
run;


***4. Create dataset for QC;
略

***5. Compare;
略

總結(jié)

這篇文章介紹了處理層級(jí)關(guān)系頻數(shù)表的方法——層級(jí)拼接法。這個(gè)方法的效率比常規(guī)各層級(jí)單獨(dú)處理要高很多镐躲,推薦大家使用储玫。

這類表格的排序,可能按字母順序進(jìn)行排序萤皂,也可能按匯總組頻數(shù)倒序排列撒穷。文章也介紹了這兩種排序的處理。

SAS編程-Table:層級(jí)拼接法輸出AE SOC裆熙、PT的受試者發(fā)生率介紹了端礼,關(guān)于AE SOC、PT層級(jí)關(guān)系嵌套的處理弛车。SOC和PT是兩層嵌套齐媒,處理上比Region、Country纷跛、Site 3層嵌套要簡(jiǎn)單點(diǎn)喻括。

感謝閱讀, 歡迎關(guān)注贫奠!
若有疑問唬血,歡迎評(píng)論交流!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末唤崭,一起剝皮案震驚了整個(gè)濱河市拷恨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谢肾,老刑警劉巖腕侄,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡冕杠,警方通過查閱死者的電腦和手機(jī)微姊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來分预,“玉大人兢交,你說我怎么就攤上這事×裕” “怎么了配喳?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)凳干。 經(jīng)常有香客問我晴裹,道長(zhǎng),這世上最難降的妖魔是什么救赐? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任息拜,我火速辦了婚禮,結(jié)果婚禮上净响,老公的妹妹穿的比我還像新娘少欺。我一直安慰自己,他們只是感情好馋贤,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布赞别。 她就那樣靜靜地躺著,像睡著了一般配乓。 火紅的嫁衣襯著肌膚如雪仿滔。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天犹芹,我揣著相機(jī)與錄音崎页,去河邊找鬼。 笑死腰埂,一個(gè)胖子當(dāng)著我的面吹牛飒焦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播屿笼,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼牺荠,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了驴一?” 一聲冷哼從身側(cè)響起休雌,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎肝断,沒想到半個(gè)月后杈曲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體驰凛,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年担扑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了洒嗤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡魁亦,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出羔挡,到底是詐尸還是另有隱情洁奈,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布绞灼,位于F島的核電站利术,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏低矮。R本人自食惡果不足惜印叁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望军掂。 院中可真熱鬧轮蜕,春花似錦、人聲如沸蝗锥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)终议。三九已至汇竭,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間穴张,已是汗流浹背细燎。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留皂甘,地道東北人玻驻。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像偿枕,于是被迫代替她去往敵國(guó)和親击狮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容