2014-03-29 50 views
1

這裏是我的代碼爲什麼SAS「合併」函數會覆蓋觀察結果和偏差?

libname blood "C:\Users\owner\Desktop\SAS"; 
data blood.donors1; 
    input id type $ units; 
    cards; 
2304 o 16 
1129 a 48 
1129 a 50 
1129 a 57 
2486 b 63 
; 
run; 

data blood.donors2; 
    input id code units; 
    cards; 
6488 65 27 
1129 63 32 
5438 63 39 
2304 61 45 
1387 64 67 
; 
run; 

proc sort data=blood.donors1 out=blood.donors1; 
    by id; 
run; 

proc sort data=blood.donors2 
      out=blood.donors2; 
    by id; 
run; 

data blood.donorsmerge; 
    merge blood.donors1 (in = indonors1) blood.donors2; 
    by id; 
    if indonors1; 
run; 

下面是結果表donorsmerge

enter image description here


1129 a 48得到完全1129 63 32覆蓋。但行1129 a 501129 a 57被部分覆蓋。爲什麼?我閱讀文檔。在我看來,結果數據集應該包含32,正如我在上面的圖片中指出的那樣

回答

2

因爲合併並不像它看起來那樣 - 具體地說,它不像SQL連接那樣操作。

在引擎蓋下,它的工作原理是,對於每個組,它讀取左側的第一行;那麼它會找到一個匹配它的行。然後,如果左側數據集中的該組有多個行,則會進入下一行。如果右邊有另一行匹配,則將這兩行匹配;否則,它什麼都不做。繼續,直到按組的最後一行。在它寫出按組的最後一行之後,但在它按組讀取第一行之前,它會清除所有變量。

每個by組似乎具有相同的值爲code究其原因,是從setmerge,或update語句變量自動保持。 IE,它們不會被設置爲丟失(除了組之間,作爲merge語句的函數)。因此,對於所有三行,code設置爲63 - 第一行設置爲63,然後在此之後不更改。

但是,units出現在兩個數據集。因此,當第二行進入左側,並且右側沒有第二行時,它保持左側的值。

如果您想完全覆蓋一個變量,則需要在drop左側數據集中的列。如果您想覆蓋匹配的行並且不覆蓋匹配的行,並且您有多對一的關係(如此處所示),則需要將變量重命名爲一個數據集或另一個數據集,然後使用​​3210或coalescec函數(或邏輯)來適當地設置變量。