将Stata代码翻译成R
Posted
技术标签:
【中文标题】将Stata代码翻译成R【英文标题】:Translating Stata code into R 【发布时间】:2014-11-04 03:45:13 【问题描述】:在 R 中进行时间序列数据分析的一般新手。我在将一些 Stata 代码转换为我正在做的复制项目的 R 代码时遇到了麻烦。
Stata代码和Stata代码的意图(来自原始分析)如下:
#### Delete extra yearc observations with different wartypes #####
drop if yearc==yearc[_n+1] & wartype!="CIVIL"
drop if yearc==yearc[_n-1] & wartype!="CIVIL"
因此,翻译后,我保留该国发生内战的行,并删除同一年份发生州际战争的行。
我已经命名了数据对象(即数据集)
mywar
在 R.
我假设我以某种方式执行条件 ifelse 语句或类似的语句,例如:
invisible(mywar$yearc <- ifelse(mywar$yearc==n-1 | mywar$yearc==n+1 | mywar$wartype!=civil, NA,
mywar$yearc)) # I am assuming I cannot condition ifelse statements like this; but, this is how I imagine it
mywar <- mywar[!is.na(mywar$yearc),]
编辑: 所以也许是一个例子
> b <- c(1970, 1970, 1970, 1971, 1982, 1999, 1999, 2000, 2001, 2002)
> c <- c("inter", "civil", "intra", "civil", "civil", "inter", "civil", "civil", "civil", "civil")
> df <- data.frame(b,c)
> df$j <- ifelse(df$b==n-1 & df$b==n+1 & df$c!="civil", NA, df$b)
> df
b c j
1 1970 inter 1970
2 1970 civil 1970
3 1970 intra 1970
4 1971 civil 1971
5 1982 civil 1982
6 1999 inter 1999
7 1999 civil 1999
8 2000 civil 2000
9 2001 civil 2001
10 2002 civil 2002
所以,我试图做的是为第 1、3 和 6 行创建 NA,因为它们是我在内战开始时的逻辑回归中的重复年份(我对内战和内战不感兴趣,但定义如何) 以便我可以从我的数据集中删除这些行。在这里,我刚刚重新创建了 b 行。 (注意,这个组成的数据中缺少的是国家 ID。但假设这十个条目代表同一个国家(例如,索马里))。因此,我对如何在包含 28,000 行的数据集中删除这些类型的行很感兴趣。
【问题讨论】:
【参考方案1】:dplyr 也是一个好方法——你只需要“保持”而不是“放弃”
library(dplyr)
filter(df, (yearc != lead(yearc, 1) & yearc != lag(yearc, 1)) | wartype == "CIVIL")
【讨论】:
不错的答案。在使用包时,习惯上会添加library(dplyr)
行。我猜你也可以为第一个子句做类似!(yearc%in%c(lead(yearc,1),lag(yearc,1)))
的事情。【参考方案2】:
您关注的是 Stata 的 if
限定符,但听起来您只是想对数据框进行子集化 - 因此您在 Stata 中使用了 drop
命令。我也在 R 之前学习了 Stata,并且很困惑,因为我非常依赖 Stata 中的 if
限定符,并立即在 R 中追求 ifelse
。但是,后来我意识到 R 中更相关的技术围绕子集展开。有一个subset()
命令,但大多数人更喜欢使用括号进行子集化(参见下面的代码)。
在您最初的问题中,您问如何做两件事:
-
如何删除 C 列上编码为“inter”或“intra”的观测值(即行),以及
如何将它们标记为丢失
样本数据
b <- c(1970, 1970, 1970, 1971, 1982, 1999, 1999, 2000, 2001, 2002)
c <- c("inter", "civil", "intra", "civil", "civil", "inter", "civil", "civil", "civil", "civil")
df <- data.frame(b,c)
df
b c
1 1970 inter
2 1970 civil
3 1970 intra
4 1971 civil
5 1982 civil
6 1999 inter
7 1999 civil
8 2000 civil
9 2001 civil
10 2002 civil
1.放弃观察 如果您想删除 C 列中非“民事”的观察,您可以对数据框进行子集化以仅保留那些“民事”的案例:
df2 <- df[df$c=="civil",]
df2
b c
2 1970 civil
4 1971 civil
5 1982 civil
7 1999 civil
8 2000 civil
9 2001 civil
10 2002 civil
上面的代码创建了一个新的数据框df2,它是df的一个子集,但是你也可以完全覆盖原来的数据框:
df <- df[df$c=="civil",]
或者,如果您不喜欢您的工作区中充斥着大量数据框,您可以生成一个新的然后删除旧的:
df2 <- df[df$c=="civil",]
rm(df)
2。将观察标记为缺失 如果您想在 C 列中标记非“公民”的观察,您可以通过将它们覆盖为 NA 来做到这一点:
df$c[df$c != "civil"] <- NA
df
b c
1 1970 <NA>
2 1970 civil
3 1970 <NA>
4 1971 civil
5 1982 civil
6 1999 <NA>
7 1999 civil
8 2000 civil
9 2001 civil
10 2002 civil
然后您可以使用列表删除(请参阅na.omit()
命令)从您正在执行的任何分析中删除案例。
旁注 当 b 列是重复的并且 c 列是“inter”或“intra”时,您的原始 Stata 代码会寻求子集。但是,您的样本数据的呈现方式似乎是一个多余的问题,这就是为什么我上面的解决方案只查看 c 列。但是,如果您想尽可能地匹配您的 Stata 代码,您可以通过
df <- df[order(df$b, df$c),]
df$duplicate <- duplicated(df$b)
df2 <- df[df$c=="civil" & df$duplicate==FALSE,]
哪个
-
按年份按时间顺序排列数据,然后按战争字母顺序排列
创建一个新变量,指定 b 列是否为重复年份
对数据框进行子集化以删除不需要的情况。
【讨论】:
【参考方案3】:尝试将您的 |
运算符更改为 &
。
这是一些虚构的数据:
R> b <- c(rep(1:4, each=3))
R> c <- 1:length(b)
R> df <- data.frame(c,b)
R> df$j <- ifelse(df$b != 2 & df$b != 3 & df$b != 1, NA, df$b)
R> df
c b j
1 1 1 1
2 2 1 1
3 3 1 1
4 4 2 2
5 5 2 2
6 6 2 2
7 7 3 3
8 8 3 3
9 9 3 3
10 10 4 NA
11 11 4 NA
12 12 4 NA
代码的最后一行 mywar <- mywar[!is.na(mywar$yearc),]
也应该可以正常工作
【讨论】:
感谢您的回复。 & 符号的工作原理是我没有收到错误,但代码没有完全翻译(或者它不像在 stata 中那样工作)。drop if yearc==yearc[_n+1] & wartype!="CIVIL"
以某种方式识别了同一年被编码为 Civil 的条目特定国家的战争和国际战争,并删除国际战争条目的行。我使用的 R 代码不会丢弃任何东西。我现在不确定我必须设置什么 mywar$yearc==
才能获得与 stata 代码相同的删除行。我认为我所拥有的是大约 90% 的解决方案。再次感谢您的意见,这很有帮助。
你可能已经看过了,但是当我在学习 stata 后学习 R 时,我发现这个网站非常有帮助:ats.ucla.edu/stat/r/faq以上是关于将Stata代码翻译成R的主要内容,如果未能解决你的问题,请参考以下文章
如何将这些伪 unicode 数据声明代码翻译成 MASM 风格的代码?
将 UIView 动画 Swift 代码翻译成 Objective-C
Scala Slick 如何将 Scala 代码翻译成 JDBC?