3

私は、投票所から人々が住んでいる距離に焦点を当てて、誰かが投票する可能性を高める要因に関する研究プロジェクトを行っています. 何百万人もの個人の完全な有権者登録と有権者履歴。誰かが (直接、不在、期日前、または暫定的に) 投票したり、投票しない (未登録、登録したが投票しなかった、または投票する資格がない) 方法はいくつかあります。私のデータには、特定の選挙で誰かがどのように投票したかを示す列 (29) が付属しています。NULL は未登録、V は対面などを意味します。

回帰分析のために、投票者のタイプごとに異なる列を作成し (1 は賛成、0 は反対、列番号 68 ~ 74)、別の 1/0 列 (75 番) を作成して、誰かがまったく投票したかどうかを示します。以下に書いたコードはうまくいくはずですが、私のコンピューターでは信じられないほど遅く実行されており、1 時間経っても 1000 行目にさえ到達できませんでした。速度を除いて、完全に機能します。大学のスーパーコンピュータ*の使用が認められたが、より高速なアルゴリズムを見つけたい。ラップトップとスーパーコンピューター*の両方に R と STATA があり、どちらも喜んで使用します。

dcv.new <- read.csv("VoterHist.csv", header=TRUE)
# I previously set columns 68-75 to default to 0
for(i in 1:nrow(dcv.new))
{
  if(is.na(dcv.new[i,29]))
  {
    dcv.new[i,69] <- 1
  }
  else if(dcv.new[i,29]=="V")
  {
    dcv.new[i,68] <- 1
    dcv.new[i,75] <- 1
  }
  else if(dcv.new[i,29]=="A")
  {
    dcv.new[i,70] <- 1
    dcv.new[i,75] <- 1
  }
  else if(dcv.new[i,29]=="N")
  {
    dcv.new[i,71] <- 1
  }
  else if(dcv.new[i,29]=="E")
  {
    dcv.new[i,72] <- 1
  }
  else if(dcv.new[i,29]=="Y")
  {
    dcv.new[i,73] <- 1
  }
  else if(dcv.new[i,29]=="P")
  {
    dcv.new[i,74] <- 1
    dcv.new[i,75] <- 1
  }
  else if(dcv.new[i,29]=="X")
  {
    dcv.new[i,74] <- 1
    dcv.new[i,75] <- 1
  }
}

*技術的には「ハイ パフォーマンス コンピューティング クラスター」ですが、正直なところ、スーパーコンピューターの方がクールに聞こえます。

4

2 に答える 2

16

R は主にベクトル化されているため、ループの代わりにベクトル化された操作を探します。この場合、個々の行ではなく行列全体で機能するように、各操作をベクトル化できます。

最初の 3 つのif elseステートメントは次のとおりです。

dcv.new[is.na(dcv.new[,29]), 69] <- 1
dcv.new[dcv.new[,29]=="V", c(68,75)] <- 1
dcv.new[dcv.new[,29]=="A", c(70,75)] <- 1
....

あなたはその考えを得る必要があります。

いくつかの説明:

ここで行っているのは、 の特定の列からdcv.new基準 ( など) を満たす行を選択し、1 回の操作で の選択した各要素に== "V"値を割り当てることです。R は、選択したすべての要素を満たすのに必要な長さと同じになるように、割り当てた をリサイクルします。1dcv.new1

更新のために一度に複数の列を選択する方法に注意してください:行のみdcv.new[x , c(68,75)]の列 68 と 75 を更新します。ここで、は更新する必要がある行にインデックスを付ける論理ベクトルです。論理ベクトルは、 のようなステートメントによって生成されます。これらは、 equalsの要素の場合とそうでない場合を返します。x xdcv.new[,29]=="V"TRUEdcv.new[,29]"V"FALSE

でも...!

回帰の場合、R にダミー変数の行列を作成させることができます。手作業で行う必要はありません。列のdcv.new[, 29]名前がvoterType. それを強制的に要因にすると

dcv.new <- transform(dcv.new, voterType = factor(voterType))

数式表記を使用してモデルを適合させると、次のことができます。

mod <- lm(response ~ voterType, data = dcv.new)

R は適切なコントラストを作成してvoterType、正しい自由度を使用します。デフォルトでは、R は因子の最初の水準を基準水準として使用するため、モデル係数はこの参照水準からの偏差を表します。voterType係数に変換した後の参照レベルを確認するには、次のようにします。

with(dcv.new, levels(voterType)[1])

上記のような式を取るほとんどのモデリング関数は、私が説明し、以下に示すように機能することに注意してください。lm()モデルに限定されません。

ここに小さな例があります

set.seed(42)
dcv.new <- data.frame(response = rnorm(20),
                      voterType = sample(c("V","A","N","E","Y","P","X",NA), 20, 
                                         replace = TRUE))
head(dcv.new)

> head(dcv.new)
    response voterType
1  1.3709584         E
2 -0.5646982         E
3  0.3631284         V
4  0.6328626      <NA>
5  0.4042683         E
6 -0.1061245      <NA>

モデルは次のように適合できます。

mod <- lm(response ~ voterType, data = dcv.new)
summary(mod)

この場合与える

> mod <- lm(response ~ voterType, data = dcv.new)
> summary(mod)

Call:
lm(formula = response ~ voterType, data = dcv.new)

Residuals:
    Min      1Q  Median      3Q     Max 
-2.8241 -0.4075  0.0000  0.5856  1.9030 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)  
(Intercept)   -2.656      1.425  -1.864   0.0952 .
voterTypeE     2.612      1.593   1.639   0.1356  
voterTypeN     3.040      1.646   1.847   0.0978 .
voterTypeP     2.742      1.646   1.666   0.1300  
voterTypeV     2.771      1.745   1.588   0.1468  
voterTypeX     2.378      2.015   1.180   0.2684  
voterTypeY     3.285      1.745   1.882   0.0925 .
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 1.425 on 9 degrees of freedom
  (4 observations deleted due to missingness)
Multiple R-squared: 0.3154, Adjusted R-squared: -0.1411 
F-statistic: 0.6909 on 6 and 9 DF,  p-value: 0.6635 

魔法はすべて数式コードで発生しますが、本質的に舞台裏で起こることは、R が数式で名前が付けられたすべての変数を見つけると、本質的に次のようなものを呼び出すことになります。

model.matrix( ~ voterType, data = dcv.new)

基になる行列代数と QR 分解に必要な共変量行列を生成します。上記のコードは、小さな例では次のようになります。

> model.matrix(~ voterType, data = dcv.new)
   (Intercept) voterTypeE voterTypeN voterTypeP voterTypeV voterTypeX
1            1          1          0          0          0          0
2            1          1          0          0          0          0
3            1          0          0          0          1          0
5            1          1          0          0          0          0
8            1          0          0          1          0          0
10           1          0          0          0          0          0
11           1          0          1          0          0          0
12           1          0          1          0          0          0
13           1          1          0          0          0          0
14           1          0          0          0          0          1
15           1          0          0          0          1          0
16           1          0          0          1          0          0
17           1          0          0          1          0          0
18           1          0          0          0          0          0
19           1          0          1          0          0          0
20           1          0          0          0          0          0
   voterTypeY
1           0
2           0
3           0
5           0
8           0
10          1
11          0
12          0
13          0
14          0
15          0
16          0
17          0
18          0
19          0
20          1
attr(,"assign")
[1] 0 1 1 1 1 1 1
attr(,"contrasts")
attr(,"contrasts")$voterType
[1] "contr.treatment"

これは、コードでやりたいことです。したがって、本当に必要な場合は、model.matrix()私が示しているように、マトリックスを生成するために使用することもできます - 必要のない属性を取り除いてください。

この場合、基準レベルは"A"次のとおりです。

> with(dcv.new, levels(voterType)[1])
[1] "A"

(Intercept)これは、 からの出力の列によって表されますmodel.matrix。これらの処理は、参照レベルからの偏差のコードを対比することに注意してください。-1(0r +0)を追加して式の切片を抑制することで、ダミーの値を取得できます。

> model.matrix(~ voterType - 1, data = dcv.new)
   voterTypeA voterTypeE voterTypeN voterTypeP voterTypeV voterTypeX voterTypeY
1           0          1          0          0          0          0          0
2           0          1          0          0          0          0          0
3           0          0          0          0          1          0          0
5           0          1          0          0          0          0          0
8           0          0          0          1          0          0          0
10          0          0          0          0          0          0          1
11          0          0          1          0          0          0          0
12          0          0          1          0          0          0          0
13          0          1          0          0          0          0          0
14          0          0          0          0          0          1          0
15          0          0          0          0          1          0          0
16          0          0          0          1          0          0          0
17          0          0          0          1          0          0          0
18          1          0          0          0          0          0          0
19          0          0          1          0          0          0          0
20          0          0          0          0          0          0          1
attr(,"assign")
[1] 1 1 1 1 1 1 1
attr(,"contrasts")
attr(,"contrasts")$voterType
[1] "contr.treatment"
于 2013-03-19T22:22:25.710 に答える
6

コードをベクトル化する必要があります。そして、多くの場合は忘れてください

dcv.new[is.na(dcv.new[,29]),69] <- 1
dcv.new[dcv.new[,29] == "V", c(68, 75)] <- 1

...。enter code here

必要に応じて続行します

于 2013-03-19T22:21:02.490 に答える