2017-03-22 41 views
1

我希望爲SAS中的合併數據創建變量。然而,這似乎比人們想象的要困難。動態合併數據

例如,我將有:

var1 
1 
2 
3 
5 
11 
17 
... 

我想擁有的3箱尺寸:

var1 bin_var 
1 1 
2 1 
3 1 
5 2 
11 4 
17 6 
... 

,我想出了一個辦法通過循環在整個範圍內做到這一點:

%do i=&bin_min %to &bin_max %by &bin_size; 
data foobar; 
    set foobar; 
     if (&i =< var_to_bin < (&i+&bin_size)) then; bin_var=&i; 
run; 
%end; 

但是,這是非常緩慢的,更不用說只是簡單的愚蠢。任何人都知道更好的方法來完成這個?

回答

2

當然,您不必在Data Step之外循環,您可以在Data Step中執行此操作並獲得相同的結果。

data foobar; 
    set foobar; 
    %do i=&bin_min %to &bin_max %by &bin_size; 
     if (&i =< var_to_bin < (&i+&bin_size)) then; bin_var=&i; 
    %end; 
run; 

或者你可以只使用一些函數並放棄循環。

data have; 
input var1; 
datalines; 
1 
2 
3 
4 
5 
6 
7 
15 
17 
28 
21 
; 

%let bin_size=3; 
%let bin_min=1; 
%let bin_max=6; 

data want; 
set have; 
bin = max(&bin_min,min(&bin_max,floor((var1-1) /&bin_size)+1)); 
run; 
+0

這幾乎是完美的。如果我設置bin_min = 2,那麼前幾個就會出錯。但是這可以通過在bin-line之前的步驟來處理。 – pinegulf

+0

您希望如何處理超出最小和最大垃圾箱數量的值? – DomPazz

+0

取決於案例,但我認爲沿着以下幾點:%if var1 max bin then bin_var =。 – pinegulf

1

如何使用簡單的劃分?如果需要,您可以添加額外的代碼來處理bin_min/bin_max問題。

data want; 
    set have; 
    bin_var= ceil(var1/&bin_size.); 
run; 
+0

這與Dom的第二個解決方案或多或少相同,但我認爲使用'ceil'而不是'floor'更直接。 – Joe

+0

您仍然需要min(max()),因爲他想設置bin數字的邊界。 – DomPazz

+0

我傾向於在這些問題的C型整數除法中,floor(a/b)是SAS模擬。我的大腦只是默認它... – DomPazz