質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
RStudio

RStudioは、Rのプログラミングを効率化する統合開発環境です。統計計算とグラフィックスができるプログラミング言語であるRのIDEでOSSで公開されています。ソースコードやコンソールなどが一つの画面に見やすく配置されている点が特徴。コマンド名以外に、関数名やパッケージ名も補完できます。

R

R言語は、「S言語」をオープンソースとして実装なおした、統計解析向けのプログラミング言語です。 計算がとても速くグラフィックも充実しているため、数値計算に向いています。 文法的には、統計解析部分はS言語を参考にしており、データ処理部分はSchemeの影響を受けています。 世界中の専門家が開発に関わり、日々新しい手法やアルゴリズムが追加されています。

Q&A

解決済

2回答

1028閲覧

【R】パネルデータで複雑な条件分岐がある変数作成コードを組みたい

discipulus

総合スコア1

RStudio

RStudioは、Rのプログラミングを効率化する統合開発環境です。統計計算とグラフィックスができるプログラミング言語であるRのIDEでOSSで公開されています。ソースコードやコンソールなどが一つの画面に見やすく配置されている点が特徴。コマンド名以外に、関数名やパッケージ名も補完できます。

R

R言語は、「S言語」をオープンソースとして実装なおした、統計解析向けのプログラミング言語です。 計算がとても速くグラフィックも充実しているため、数値計算に向いています。 文法的には、統計解析部分はS言語を参考にしており、データ処理部分はSchemeの影響を受けています。 世界中の専門家が開発に関わり、日々新しい手法やアルゴリズムが追加されています。

0グッド

0クリップ

投稿2021/05/05 04:37

編集2021/05/07 02:47

前提と実現したいこと

パネルデータで変数を作るコードを組んでいます。条件分岐が複雑で、上手くいきません。

前提:データセット

以下のように、4カ国(米日仏独)の2001年から2010年までのデータがあるとします。
※データはあくまで仮のものです。実際のデータは1975年から2015年までの160カ国をカバーしています。
ここで turnover変数は軍の司令官の交代があった年を示すダミー変数、left変数はその年の政府が左派であるかどうかを示すダミー変数です。それぞれ所々欠損があります。

R

1country <- rep(c("United States", "Japan", "France", "Germany"), each = 10) 2year.1 <- 2001:2010 3year <- rep(year.1, 4) 4turnover <- c(0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 5 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 6 NA, NA, 1, 0, 0, 1, 0, 0, 1, 0, 7 0, 0, 1, NA, NA, 0, 1, 0, 0, 1) 8left <- c(0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 9 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 10 1, 1, 0, 0, 0, 0, 0, 0 , 1, 1, 11 NA, NA, NA, 1, 1, 1, 1, 0, 0, 0) 12 13data <- data.frame( 14 country = country, 15 year = year, 16 turnover = turnover, 17 left = left 18)
countryyearturnoverleft
United States200100
United States200200
United States200310
United States200401
United States200501
United States200601
United States200711
United States200801
United States200900
United States201000
Japan200101
Japan200201
Japan200301
Japan200401
Japan200510
Japan200600
Japan200701
Japan200801
Japan200910
Japan201010
France2001NA1
France2002NA1
France200310
France200400
France200500
France200610
France200700
France200800
France200911
France201001
Germany20010NA
Germany20020NA
Germany20031NA
Germany2004NA1
Germany2005NA1
Germany200601
Germany200711
Germany200800
Germany200900
Germany201010

実現したいこと

このデータセットで実現したいのは、どのような政府(つまり左派かそうでないか)が軍の司令官を交代させたのかを示す変数です。
例えばUnited Statesでは2003年と2007年に軍の司令官が交代していますが、2003年時にleftは0、2007年時にleftは1です。

したがって、2001年から2003年にかけては非左派に交代させられた司令官が、2004年から2007年には左派に交代させられた司令官がそれぞれ在任しており、そのことを示す変数gov_at_toを以下の要領で作成したいです。

countryyearturnoverleftgov_at_to
United States2001000
United States2002000
United States2003100
United States2004011
United States2005011
United States2006011
United States2007111

しかし、3点complicationがあります。

  • United Statesは2007年に司令官の交代があったのを最後に、観察打ち切りの2010年まで交代が発生していないため、このような場合はNAを入れたい。
  • フランスでは2003年に交代があったが、2001年と2002年はturnoverが欠損値となっており、交代の有無が確認できないため、このような場合はNAを入れたい。
  • ドイツでは2003年に交代があったが、この時のleftは欠損値となっており、どの政府が交代させたか確認できないため、このような場合はNAを入れたい。

以上の条件を全て考慮すると、以下のような変数が最終的に入ります。

countryyearturnoverleftgov_at_to
United States2001000
United States2002000
United States2003100
United States2004011
United States2005011
United States2006011
United States2007111
United States200801NA
United States200900NA
United States201000NA
Japan2001010
Japan2002010
Japan2003010
Japan2004010
Japan2005100
Japan2006001
Japan2007011
Japan2008011
Japan2009101
Japan2010100
France2001NA1NA
France2002NA1NA
France2003100
France2004000
France2005000
France2006100
France2007001
France2008001
France2009111
France201001NA
Germany20010NANA
Germany20020NANA
Germany20031NANA
Germany2004NA1NA
Germany2005NA1NA
Germany2006011
Germany2007111
Germany2008000
Germany2009000
Germany2010100

試したことと問題

データをpdata.frame()でパネルデータ化し、以下のようなコードを組んでみました。

R

1data2 <- data.frame() 2 3data$orig.nr <- 1:nrow(data) #オリジナルのデータセットの順番を保存 4 5for(key_country in unique(data$country)){ 6 subdata <- subset(data, country==key_country) # 国別にサブデータセットを作成 7 subdata[nrow(subdata), "gov_at_to"] <- ifelse(subdata[nrow(subdata), "tunover"] == 1, 0, NA) 8 for(i in (nrow(subdata)-1):1){ 9 if (subdata[i, "tunover"] == 0){ 10 subdata[i, "gov_at_to"] <- subdata[i+1, "govt_at_to"] 11 } else if (subdata[i, "tunover"] == 1 & subdata[i, "left"] == 0){ 12 subdata[i, "gov_at_to"] <- 0 13 } else if (subdata[i, "tunover"] == 1 & subdata[i, "left"] == 1){ 14 subdata[i, "gov_at_to"] <- 1 15 } else { 16 subdata[i, "gov_at_to"] <- NA 17 } 18 } 19 data2 <- rbind(data2, subdata) 20} 21 22data2 <- data2[order(data2$orig.nr),] #オリジナルのデータセットの順番に戻す 23data2$orig.nr <- NULL 24print(data2)

しかしながら、for文の実行で

if (subdata[i, "turnover"] == 0) { でエラー:

TRUE/FALSE が必要なところが欠損値です

というエラーメッセージが出てしまいます。
おそらく条件分岐の設定がうまくいっていないためこのような形になっていると考えられるのですが、解決策を教えていただけましたら幸いです。

# 環境
R version 4.0.3
R Studio Version 1.2.5033
動かしているパッケージはこちら

R

1library(foreign) 2library(tidyverse) 3library(lme4) 4library(dotwhisker) 5library(arm) 6library(mvtnorm) 7library(pastecs) 8library(stargazer) 9library(ggeffects) 10library(lubridate) 11library(ggsci) 12library(plm) 13library(pglm) 14library(gridExtra) 15library(haven) 16library(countrycode) 17library(magrittr) 18library(survival) 19library(bife) 20library(survminer) 21library(lmtest) 22library(multiwayvcov)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

turnoverとleftの条件に合わせてgov.at.toに数字を入れた後、tidyrパッケージのfill()を使って残りを埋めました。NAの挿入だけは人力でなんとかしました。

投稿2021/05/10 08:47

discipulus

総合スコア1

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

どこでエラーが発生したかは、エラー発生直後traceback()してみると分かります。

予想だけすると、

subdata[i+1, "govt_at_to"]

これは空データなのでは。

投稿2021/05/05 06:13

KojiDoi

総合スコア13671

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

discipulus

2021/05/05 06:38

ご回答ありがとうございます。 当該部分をsubdata[i+1, "govt_at_to"] からsubdata[i+1, "gov_at_to"] に直して実行してみましたが、同じエラーメッセージが出ました。 traceback()を実行してみたところ、 2: `[<-.data.frame`(`*tmp*`, nrow(subdata), "gov_at_to", value = logical(0)) 1: `[<-`(`*tmp*`, nrow(subdata), "gov_at_to", value = logical(0)) と出ました。 恐れながらこれが何を意味するのかよく理解できていないため、ご教授いただけますと幸いです。
KojiDoi

2021/05/05 07:06

Rのメッセージは、確かに不親切極まりないです。 ここでvalue=logical(0)というのが登場していますが、logical(0)つまり「長さ0の論理型のベクトル」は、存在しない値を参照した演算を試みたりすると出てきます。 それで、subdata[nrow(subdata), "to.dummy"]というのを参照していますが、これはどこでどう定義しているのでしょうか。
discipulus

2021/05/05 07:15

ありがとうございます。 "to.dummy"というのはデータ部分の例示スクリプトのtunover変数のことです。(元のデータの変数名を使ってしまいました) とりあえず、例示コードの"to.dummy"を"turnover"に変え実行してみましたが、今度は if (subdata[i, "turnover"] == 0) { でエラー: TRUE/FALSE が必要なところが欠損値です というエラーが出ました。
KojiDoi

2021/05/07 12:44

実数が入っていない(NA)ために==の判定ができへんでーというエラーなのは、メッセージを読めば解ると思います。 であれば、その判定をする前にis.na()で条件判定してnaでない場合のみ==の判定するように2段構えのコードを組めばよいだけですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問