coi*_*oip 0 sorting r subset data-mining stata
尝试从Stata过渡到R是令人兴奋和具有挑战性的,但我仍在R中努力的一个领域是数据探索,然后是后续的变量创建.具体来说,如何
计算变量的值(Stata的计数命令)
count if var 2==3
/* counts the number of observations that have a value of 3 on var2 */
Run Code Online (Sandbox Code Playgroud)列出符合条件的观察结果(Stata's if qualifier)
list id if var7 < 8
/*lists the ID of observations with a value less than 8 on var7 */
Run Code Online (Sandbox Code Playgroud)按分组变量制表(Stata的bysort命令)
bysort var3: tab1 var2 var9 if var8=2 | var1 !=11
/* create a two-way frequency table for those observations of var2 and var9 where
var8 is 2 or var1 isn't 11 */
Run Code Online (Sandbox Code Playgroud)从另一个创建一个新变量(Stata的egen命令)
egen var3 = count(var1), by(var2)
/* creates var3 as the total observations in var1, for each category in var2;
here var2 is a categorical variable, so, this code seeks to count the frequency
of var1 (say, 'trades' among NFL teams), counted separately by each category of
var2 (say, 32 different NFL teams). */
Run Code Online (Sandbox Code Playgroud)我试着在最后回答你的问题.首先,一个示例数据框用于:
set.seed(123)
df <- data.frame(id=c(paste0(letters[1:10], 1:10)), matrix(sample(1:20, 500, replace=T), nrow=100, ncol=5))
colnames(df)[2:6] <- paste0("var", 1:5)
Run Code Online (Sandbox Code Playgroud)
对于第一个问题,我不确定为什么你不会这样做table(var2),但如果你想,有几种方法可以做到这一点.
count if var2==3 /* counts the number of observations that
have a value of 3 on var2 */
Run Code Online (Sandbox Code Playgroud)
有了第一个,我试图复制Stata在你要求计数时所做的事情.这里我们为数据框子集var2==3,然后计算行数.
nrow(df[df$var2==3, ])
Run Code Online (Sandbox Code Playgroud)
您可以通过获取向量来更直接地执行此操作,向量df$var2==3是TRUE/FALSE具有相同长度的逻辑向量nrow(df),并对值进行求和,这将隐式地将向量从逻辑转换为0/1
sum(df$var2==3)
Run Code Online (Sandbox Code Playgroud)
第二个问题也基本上归结为子集化,一般来说,我认为你将if在Stata中使用的内容归结为使用相同的逻辑条件对R数据帧进行子集化.
list id if var7 < 8 /* lists the ID of observations with a
value less than 8 on var7 */
Run Code Online (Sandbox Code Playgroud)
因此,我们通过将行限制为满足条件var5 < 8并选择id我们想要的变量来对数据框进行子集化.
df$id[df$var5 < 8]
# or
df[df$var5 < 8, "id"]
# or
subset(df, var5 < 8, select="id")
# or
with(df, id[var5 < 8])
Run Code Online (Sandbox Code Playgroud)
人们通常不建议 subset.如果要选择名称包含在另一个对象中的变量,第二种方法很有用,例如
want <- c("id", "var1")
df[df$var5 < 8, want]
Run Code Online (Sandbox Code Playgroud)
最后两个有点棘手.
bysort var3: tab1 var2 var9 if var8=2 | var1 !=11 /* create a series of separate
two-way frequency tables for those observations of var2
and var9 where var8 is 2 or var1 isn't 11 */
Run Code Online (Sandbox Code Playgroud)
我们可以通过首先对我们想要的数据进行子集化,然后使用by制表var2和var3by来实现var1.
foo <- df[df$var4==20 | df$var5==7, ]
by(foo, foo$var1, function(x) table(x[, c("var2", "var3")]))
Run Code Online (Sandbox Code Playgroud)
该function(x)部分被称为匿名函数,我认为,当你使用像功能是常见的by,apply等呼吁by将打破foo由成片var1,然后把它传递为我们的匿名功能,即论证x.传递的是一个子集foo,因此是一个包含原始变量名称的数据框,这就是我们可以x按照相同的方式进行子集化的原因foo.
从技术上讲,您也可以将所有三个添加到table调用中,但这对于如此多的变量值不起作用:
table(foo$var2, foo$var3, foo$var1)
Run Code Online (Sandbox Code Playgroud)
最后一个问题有点奇怪.不会的计数var1的var2只是值的频率var2,除非有遗漏值?我假设那时缺少值.
egen var3 = count(var1), by(var2) /* creates var3 as the total observations in
var1, for each category in var2 */
Run Code Online (Sandbox Code Playgroud)
所以这里我们分解df为分区df$var2,然后应用一个函数来计算非缺失值var3.最后一位将其更改为具有var2值和非缺失var3计数的数据帧.
v3obs <- by(df, df$var2, function(x) sum(!is.na(x$var3)))
v3obs[]
v3obs <- data.frame(var2=names(v3obs[]), var6=v3obs[])
Run Code Online (Sandbox Code Playgroud)
我们现在可以将结果合并回我们的数据框以复制内容egen.
foo <- merge(foo, v3obs, by="var2", type="left")
Run Code Online (Sandbox Code Playgroud)
您也可以使用for循环执行此操作,循环遍历行,子集var3为值,var2并填充计数非缺失观察值.这可能更容易阅读,但效率较低.可能还有一些更好的方法,我不知道,并且by对我来说不是那么直观(我也来自Stata背景),所以我通常会尽量避免它.