2017-08-23 54 views
0

我期望根據當前行的值有條件地更改前一行中的變量的值。有條件地更改前一行的值

對於其中狀態= 1,則我想前面的行中的狀態中的所有行也等於1

下面是一個例子的數據集:

ID Status 
1 0 
1 1 
1 1 
2 0 
2 1 
2 0 
2 0 
2 1 

我想是:

ID Status 
1 1 
1 1 
1 1 
2 1 
2 1 
2 0 
2 1 
2 1 

的代碼,我想是這樣的:

if status=1 then lag(status)=status; 

請注意,我所有的first.id都有一個status=0

這就是說,我承認爲什麼這不起作用。請記住,我是一個初學者程序員,並沒有理解爲以前提到的類似問題給出的代碼。

謝謝!

回答

0

如果你添加一個變量的原始行號(_n_),您可以使用排序的descending數據集排列順序顛倒過來,然後用滯後算:

data one; 
infile cards; 
input id status; 
sequence=_n_; 
cards; 
1 0 
1 1 
1 1 
2 0 
2 1 
2 0 
2 0 
2 1 
; 
run; 

proc sort data=one; 
by id descending sequence; 
run; 

我不知道是否要先前的值用於傳遞ID。如果ID不同,此示例不會查看滯後值(not first.id)。

data two; 
set one; 
by id descending sequence; 
if not first.id and lag(status) = 1 then status=1; 
run; 

proc sort data=two; 
by id sequence; 
run; 
+0

謝謝大衛!我確實需要區分ID,以便過程重置每個ID。 – Stuff

0

不要以爲它會改變上一行,你可以把它看成是一個展望未來的問題。也就是說,當你正在閱讀每條記錄時,你想看看下一條記錄,看看狀態值是否爲1.

做一個前瞻的一種方法是將數據集與自己合併。這有點棘手,但對於想要了解DATA步驟的初學者來說是一個很好的教訓。如果您合併兩個沒有BY語句的數據集,它們將按順序排列在一起(從每個數據集讀取的第一條記錄合併在一起,然後從每個數據集中讀取第二條記錄等)。如果您將數據集與自身合併,並且第二次開始閱讀第二個觀察數據,則您會看到前景。這是一個艱難的句子,但使用您的樣本數據:

options mergenoby=nowarn ; 

data lookahead ; 
    merge have 
     have (keep=status rename=(status=NextStatus) firstobs=2) 
    ; 
run ; 

options mergenoby=error ; 

所以你讀了數據集中的第二次,firstobs選項就開始閱讀第二觀察,你只讀狀態變量,並將其重命名到NextStatus。結果是:

      Next 
Obs id status Status 

    1  1  0   1 
    2  1  1   1 
    3  1  1   0 
    4  2  0   1 
    5  2  1   0 
    6  2  0   0 
    7  2  0   1 
    8  2  1   . 

花時間瞭解上述步驟,並玩一下。 MERGENOBY選項控制當合並步驟沒有BY時,SAS是否引發錯誤,警告或沒有警告。我總是將MERGENOBY設置爲錯誤,因爲如果合併步驟沒有BY語句,99%的時間是偶然的遺漏。當我故意與no進行合併時,我在步驟之前設置了MERGENOBY = NOWARN,然後立即返回到MERGENOBY = ERROR。一旦你瞭解瞭如何工作,所有你需要的是一個分配來獲得你想要的輸出。

options mergenoby=nowarn; 

data want; 
    merge have 
     have (keep=status rename=(status=NextStatus) firstobs=2) 
    ; 
    if NextStatus=1 then Status=1; 
    drop NextStatus; 
run; 

options mergenoby=error; 


Obs id status 

1  1  1 
2  1  1 
3  1  1 
4  2  1 
5  2  1 
6  2  0 
7  2  1 
8  2  1 

請注意,這是一個簡單的預測,它將通過值向前看。因此,如果您曾經擁有狀態爲0的ID的最後一個記錄,並且狀態爲1的下一個ID的第一個記錄,則會將狀態重置爲1.如果您不需要,可以將邏輯添加到檢查NextID是否與當前ID匹配。

+0

我不認爲這將正確處理多個ID值。當您處於ID = 1的最後一條記錄時,您不想考慮ID = 2的第一條記錄的狀態。 – Tom

+0

同意,這是我在最後一段中指出的。從OP的問題來看,我不清楚他們想如何處理ID的變化,或者他們曾經有過一個ID最後一個記錄爲0的情況。 – Quentin