2013-01-31 71 views
2

背景:我在幾年中使用了一些人口普查公開使用的微數據樣本(特別是美國社區調查)來檢查完成不同學位(例如高中文憑,學士學位,碩士學位)的人的行爲。具有該公共使用文件的變量稱爲「學校教育」。問題在於變量「學校教育」中包含的代碼每年都在變化。例如,對於截至2007年的文件,「13」值反映完成學士學位,但從2008年開始,當有人完成學士學位時,值變爲「21」。如何比較數據框中的矢量值與R中的常量?

目標:創建一個新的「學位Competed」變量,將「學校」代碼翻譯爲反映已完成的學位等級,同時考慮文件的年份。 物流:所有年份的文件都被連接在一起,爲了審查目的,我必須按照原樣處理文件,而不是在文件到達這一點之前對其進行更正。

現有代碼:這是我試過的。

if  (original.file$year %in% c(2000,2001)) { 
    if  (original.file$Schooling <= 08) {original.file$degree.completed <- 0} 
    else if (original.file$Schooling <= 10) {original.file$degree.completed <- 1} 
    else if (original.file$Schooling <= 12) {original.file$degree.completed <- 2} 
    else if (original.file$Schooling == 13) {original.file$degree.completed <- 3} 
    else if (original.file$Schooling == 14) {original.file$degree.completed <- 4} 
    else if (original.file$Schooling == 15) {original.file$degree.completed <- 5} 
    else if (original.file$Schooling == 16) {original.file$degree.completed <- 6} 
    } 
else if (original.file$year %in% c(2002,2003,2004,2005,2006,2007)) { 
    if  (original.file$Schooling <= 08) {original.file$degree.completed <- 0} 
    else if (original.file$Schooling <= 11) {original.file$degree.completed <- 1} 
    else if (original.file$Schooling == 12) {original.file$degree.completed <- 2} 
    else if (original.file$Schooling == 13) {original.file$degree.completed <- 3} 
    else if (original.file$Schooling == 14) {original.file$degree.completed <- 4} 
    else if (original.file$Schooling == 15) {original.file$degree.completed <- 5} 
    else if (original.file$Schooling == 16) {original.file$degree.completed <- 6} 
    } 
else if (original.file$year %in% c(2008,2009,2010,2011)) { 
    if  (original.file$Schooling <= 15) {original.file$degree.completed <- 0} 
    else if (original.file$Schooling <= 19) {original.file$degree.completed <- 1} 
    else if (original.file$Schooling == 20) {original.file$degree.completed <- 2} 
    else if (original.file$Schooling == 21) {original.file$degree.completed <- 3} 
    else if (original.file$Schooling == 22) {original.file$degree.completed <- 4} 
    else if (original.file$Schooling == 23) {original.file$degree.completed <- 5} 
    else if (original.file$Schooling == 24) {original.file$degree.completed <- 6} 
    } 

問題:我得到這個類型的以下警告消息。

警告消息:

1:在如果(original.file $今年%C(2000年,2001年)%){:條件具有長度> 1且僅第一個元素將被用來

2:如果(original.file $學制< = 8){:條件具有長度> 1且僅第一個元素將被用來

3:在如果(original.file $學制< = 10 ){:條件長度> 1,只有第一個元素將被使用

問題:我知道在這裏有一個向量與標量問題,如果我看到StackOverflow上的其他問題,但答案似乎不適用於這種情況。這裏有什麼解決方案?

+0

'if'作用於單個布爾值你可以使用'ifelse'作用於向量,但不適合這種情況,你也可以使用你的布爾條件和子集,像'dat $ degree [dat $ year%in%2000:2001&dat $ schooling <= 8] < - 0'。 – Justin

回答

3

首先,使用cuttable代替所有的if的和else的的:

CutOffs1 <- c(0,8,10,12,13,14,15,16) 
CutOffs2 <- c(0,8,11,12,13,14,15,16) 
CutOffs3 <- c(0,15,19,20,21,22,23,24) 
CutOffs <- cbind(CutOffs1, CutOffs2, CutOffs3) 
MyTable <- apply(CutOffs, 2, function(X) cut(1:24, X, FALSE)-1) 

     CutOffs1 CutOffs2 CutOffs3 
[1,]  0  0  0 
[2,]  0  0  0 
[3,]  0  0  0 
[4,]  0  0  0 
[5,]  0  0  0 
[6,]  0  0  0 
[7,]  0  0  0 
[8,]  0  0  0 
[9,]  1  1  0 
[10,]  1  1  0 
[11,]  2  1  0 
[12,]  2  2  0 
[13,]  3  3  0 
[14,]  4  4  0 
[15,]  5  5  0 
[16,]  6  6  1 
[17,]  NA  NA  1 
[18,]  NA  NA  1 
[19,]  NA  NA  1 
[20,]  NA  NA  2 
[21,]  NA  NA  3 
[22,]  NA  NA  4 
[23,]  NA  NA  5 
[24,]  NA  NA  6 

你也將要到年cut到的因素。

original.file$Period <- cut(original.file$year, c(2000,2001, 2007, 2011), FALSE, 
          include.lowest=TRUE) 
## To demonstrate: 
    > cbind(2000:2011, cut(2000:2011, c(2000,2001, 2007, 2011), FALSE, 
+  include.lowest=TRUE)) 
     [,1] [,2] 
[1,] 2000 1 
[2,] 2001 1 
[3,] 2002 2 
[4,] 2003 2 
[5,] 2004 2 
[6,] 2005 2 
[7,] 2006 2 
[8,] 2007 2 
[9,] 2008 3 
[10,] 2009 3 
[11,] 2010 3 
[12,] 2011 3 

那麼你應該能夠做到:

Degrees <- apply(original.file, 1, function(X) MyTable[X['Schooling'], X['Period']]) 
+0

原始數據中有一些NAs,它們在臨界點中如何處理? –

+0

它們也應該導致NA,但如果它們是NA,則無法知道什麼在學校的水平某人得到了,所以你最好擺脫它們或製作一個單獨的非NA值的子集 –

0

榮譽給賈斯汀一個解決方案:

如果作用於一個布爾值。相反,你可以使用ifelse作用於矢量,但不會很適合這個。您也可以使用布爾條件和子集。類似於dat $ degree [dat $ year%in%2000:2001 & dat $ schooling < = 8] < - 0。 - 賈斯汀

最終的解決方案需要一個調整:因爲這不是一個if-then-else語句,並有幾個發言,一個「< = 8」形結構不會起作用,因爲後續的語句將取代本一。例如,如果下一行有「... < = 10] < - 1,那麼一旦調用該行,所有零將被更改爲1,依此類推,而」< = 8「必須是翻譯成%c(1:8)語句的百分比,並且必須注意使所有類似於if的語句互斥,以避免重寫先前的賦值。