2013-11-22 42 views
0

,我有以下數據:創建一個循環來排序數據一起

id date day_1...day_6...day_20 port_ent port_day_1...port_day_6...port_day_20 
    1 1/1/00  2  4  6   1  2   4    6 
    2 1/6/00  1  2  5   6  .   2    5 
    3 1/16/00 3  2  1   16  .   .    1 
    4 1/20/00 6  3  2   20  .   .    2 

我想創建變量port_day_i

day_i:給定date多少小部件是在第i 出售第天(當i = 1,這是在同一天date

port_ent:使用id = 1作爲port_day_1

標準化日期系統

port_day_i:在那個投資組合日,每個人的銷售額是多少

您入境的那一天呃組合從day_1使用數據,然後第二天你day_2

我想這個循環會工作,但它並不:

forval j = 2/100 { 
local i = `j' - port_ent + 1 
    gen port_day_`j' = . 
    replace port_day_`j' = day_`i' if `i' > 0 
} 

此代碼將讓我有一部分的方式但顯然,這將是非常麻煩的,我有超過1000天的數據

gen port_day_1 = . 
replace port_day_1 = day_1 if port_ent == 1 

gen port_day_2 = . 
replace port_day_2 = day_2 if port_ent == 1 
replace port_day_2 = day_1 if port_ent == 2 

gen port_day_3 = . 
replace port_day_3 = day_3 if port_ent == 1 
replace port_day_3 = day_2 if port_ent == 2 
replace port_day_3 = day_1 if port_ent == 3 

gen port_day_4 = . 
replace port_day_4 = day_4 if port_ent == 1 
replace port_day_4 = day_3 if port_ent == 2 
replace port_day_4 = day_2 if port_ent == 3 
replace port_day_4 = day_1 if port_ent == 4 

gen port_day_5 = . 
replace port_day_5 = day_5 if port_ent == 1 
replace port_day_5 = day_4 if port_ent == 2 
replace port_day_5 = day_3 if port_ent == 3 
replace port_day_5 = day_2 if port_ent == 4 
replace port_day_5 = day_1 if port_ent == 5 

gen port_day_6 = . 
replace port_day_6 = day_6 if port_ent == 1 
replace port_day_6 = day_5 if port_ent == 2 
replace port_day_6 = day_4 if port_ent == 3 
replace port_day_6 = day_3 if port_ent == 4 
replace port_day_6 = day_2 if port_ent == 5 
replace port_day_6 = day_1 if port_ent == 6 
+0

如果你把下方的'當地i'一個'display'一行(並註釋掉一切) ,你會在你的循環中看到'i = j'。試着用'display'i =「\'i'」,j =「\'j''並親眼看看。我想這是無意的。根據問題的措辭,我實際上無法理解你所尋求的。也許你甚至不需要循環。 –

+0

@RobertoFerrer我正在嘗試創建'port_day_i'列。我假設我的'i'的錯誤指示是我的主要問題,但我不知道如何解決它。我打開一個非循環的答案,但我不確定這會起作用。 – CJ12

+0

@RobertoFerrer如果這有幫助:初始'i'對於記錄應該是唯一的,並且應該在每個記錄的每次迭代中(從該初始'i')增加1。 – CJ12

回答

1

也許這會奏效。我無法理解你的問題背後的邏輯。我懷疑它有一個錯誤,但嘗試它。爲了更好地理解,我必須更改一些變量名稱並創建一些數據。最後,我的變量sales_i是您的day_i,我的port_sales_j是您的port_day_j

clear all 
set more off 

input id str15 date day_1 day_2 day_3 day_4 day_5 day_6 port_ent 
    1 "1/1/00"  2  4  6 9 3 21 1 
    2 "1/3/00"  1  1  5 2 4 6 3 
    3 "1/6/00"  1  2  5 1 8 76 6 
end 

list 

reshape long day_, i(id) j(day) 
rename day_ sales 
list, sepby(id) 

sort id day 
gen port_sales = . 
by id: replace port_sales = sales[_n -(port_ent - 1)] if port_ent <= day 
list, sepby(id) 

reshape wide port_sales sales, i(id) j(day) 
list id port_ent sales* 
list id port_ent port_sales* 
+0

@RobertFerrer數據已經很長了。邏輯很簡單,但我沒有很好地表達。我有來自所有這些部門的銷售數據('id'),這些數據從不重複。銷售數據從「日期」開始。我想創建一個白天的銷售累計。所以一旦一個新部門的數據開始出現,它就會被「天」添加到時間範圍內的其他部門。 – CJ12

+1

我'重塑長',因爲在我看來,更容易操縱這種方式。最後,它恢復到原來的格式。就像我說的,這段代碼似乎有效。在我的答案中使用輸入數據時,此代碼與原始帖子中的長段代碼給出了相同的結果。 –

+0

這裏對「重塑」的反對或懷疑是毫無根據的,就像你對我的建議的反應一樣。即使您將數據視爲「長期」,使其「長久」也是一種標準技術。有關上下文中的一個工作示例,請參閱http://www.stata.com/support/faqs/data-management/problems-with-reshape/。 –

0

的一個問題是,你的local是不是,不能矢量化,這是你彷彿被希望或假定。因此,當地的宏

local i = `j' - port_ent + 1 

將被解釋爲導致從評價

local i = `j' - port_ent[1] + 1 
在每個觀察

常數。

更大的問題是您的數據結構不適合用途。你有跨行的面板數據,所以你的變量是轉置的。

這給我,你想問什麼的本質,但你應該考慮是否最後reshape wide是必要的。它部分取決於你想要做什麼,但對於最可能的面板操作,這種數據結構最好長期保留。

clear 
input id day_1 day_6 day_20 port_ent 
1  2  4  6   1 
2  1  2  5   6 
3  3  2  1   16 
4  6  3  2   20 
end 
reshape long day_ , i(id) 
gen day2 = day_ + port_ent - 1 
rename day_ port_day 
reshape wide port_day , i(id _j) j(day2) 
+0

這不是面板數據。不會有'id'出現多次。我明白它不能被矢量化,但是有沒有一種方法可以在沒有重塑的情況下創建'port_day_i'?如果不是,沒有定義'j()'no,重塑似乎不起作用。 – CJ12

+0

我還添加了代碼,給出了想要的結果,但會太麻煩 – CJ12

+0

如果您喜歡但您可以反對術語「面板數據」,但是(1)您想要按照Stata術語反對穀物(2)你不解釋我的解決方案有什麼問題。當Stata提供更強大的工具來滿足你的需求時,想要在這裏循環顯然是不合常理的。 –

0

該解決方案包括一個循環,並在形式上更接近原始的嘗試:

clear all 
set more off 

input id day_1 day_2 day_3 day_4 day_5 day_6 port_ent 
    1 2  4  6 9 3 21 1 
    2 1  1  5 2 4 6 3 
    3 1  2  5 1 8 76 6 
end 

forval i = 1/6 { 
    generate port_day_`i' = . 

    local j = 1 
    while `j' <= `i' { 
     replace port_day_`i' = day_`j' if port_ent == `i' - `j' + 1 
     local j = `j' + 1 
    } 
} 

list id port_ent day* 
list id port_ent port_day* 
+0

內循環也可以使用'forval'重寫:'j'的初始化及其增量然後退出。 –

相關問題