2

背景:私は数年にわたって国勢調査の公用マイクロデータサンプル(特にアメリカンコミュニティサーベイ)を使用して、さまざまな学位(高校の卒業証書、学士号、修士号など)を修了した人々の行動を調べています。その公用ファイルを持つ変数は「Schooling」と呼ばれます。問題は、変数「Schooling」に含まれるコードが年ごとに変更されていることです。たとえば、2007年までのファイルの場合、値「13」は学士号を取得したことを反映しますが、2008年以降、誰かが学士号を取得すると値は「21」に変更されます。

目標:ファイルの年を考慮して、完了した学位レベルを反映するように「Schooling」コードを変換する新しい「DegreeCompeted」変数を作成すること。ロジスティクス:すべての年のファイルは連結されており、レビューの目的で、この時点に到達する前にファイルを修正するのではなく、そのまま使用する必要があります。

既存のコード:これが私が試したものです。

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:In if(original.file $ year%in%c(2000、2001)){:条件の長さが1より大きいため、最初の要素のみが使用されます

2:In if(original.file $ Schooling <= 8){:条件の長さが1より大きいため、最初の要素のみが使用されます

3:In if(original.file $ Schooling <= 10){:条件の長さは> 1で、最初の要素のみが使用されます

質問:StackOverflowの他の質問から見てきたように、ここに「if」に関するベクトルとスカラーの問題があることは知っていますが、答えはこの状況には当てはまらないようです。ここでの解決策は何ですか?

4

2 に答える 2

3

まず、これらすべての'と'の代わりにcutまたはを使用します。tableifelse

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']])
于 2013-01-31T19:57:35.040 に答える
0

解決策についてのジャスティンへの称賛:

単一のブール値に作用する場合。代わりに、ベクトルに作用するifelseを使用できますが、これにはあまり適していません。ブール条件とサブセット化を使用することもできます。dat $degree [dat $ year%in%2000:2001&dat $ schooling <= 8] <-0のようなもの。– Justin

最終的な解決策には1つの調整が必要でした。これはif-then-elseステートメントではなく、複数のステートメントがあるため、後続のステートメントがこれに取って代わるため、「<=8」タイプの構造は機能しません。たとえば、次の行の「... <= 10] <-1の場合、この行が呼び出されると、すべてのゼロが1に変更されます。代わりに、「<=8」は次のようになります。 %in%c(1:8)ステートメントに変換され、以前の割り当てがこのようにオーバーライドされないように、すべてのif-likeステートメントが相互に排他的になるように注意する必要があります。

于 2013-01-31T22:31:28.417 に答える