尝试从Stata过渡到R是令人兴奋和具有挑战性的,但我在R中仍在努力的一个领域是数据探索,然后是随后的变量创建。具体来说,如何
计算变量的值(Stata的 count 命令)
count if var 2==3
/* counts the number of observations that have a value of 3 on var2 */
列出满足条件的观察结果(Stata的如果限定符)
list id if var7 < 8
/*lists the ID of observations with a value less than 8 on var7 */
按分组变量制表(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 */
从另一个创建新变量(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). */
答案 0 :(得分:6)
我最后试着回答你的问题。首先,使用示例数据框:
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)
对于第一个问题,我不确定为什么你不会用table(var2)
执行此操作,但如果你愿意,有几种方法可以做到。
count if var2==3 /* counts the number of observations that
have a value of 3 on var2 */
第一个我试图复制Stata在你要求它计算时所做的事情。在这里,我们对var2==3
的数据框进行子集化,然后计算行数。
nrow(df[df$var2==3, ])
您可以更直接地执行此操作,方法是使用向量df$var2==3
,它是一个长度与TRUE/FALSE
相同的逻辑nrow(df)
向量,并对值进行求和,这将隐式转换矢量从逻辑到0/1
sum(df$var2==3)
第二个问题也基本上归结为子集化,一般来说,我认为在Stata中使用if
的内容归结为具有相同逻辑条件的R数据帧的子集化。
list id if var7 < 8 /* lists the ID of observations with a
value less than 8 on var7 */
因此,我们通过将行限制为符合条件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])
人们通常don't recommend subset
。如果要选择名称包含在另一个对象中的变量,第二种方法很有用,例如:
want <- c("id", "var1")
df[df$var5 < 8, want]
最后两个有点棘手。
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 */
我们可以首先对我们想要的数据进行子集化,然后使用by
将var2
和var3
制成var1
表格。
foo <- df[df$var4==20 | df$var5==7, ]
by(foo, foo$var1, function(x) table(x[, c("var2", "var3")]))
我认为function(x)
部分称为匿名函数,在您使用by
,apply
等函数时很常见。by
的调用将会中断foo
将var1
分成几部分,然后将其作为匿名函数的参数传递,即x
。传递的内容是foo
的子集,因此是包含原始变量名称的数据框,这就是为什么我们可以像x
一样对foo
进行分组的原因。
从技术上讲,您也可以将所有三个添加到table
调用中,但这对于如此多的变量值不能很好地运行:
table(foo$var2, foo$var3, foo$var1)
最后一个问题有点奇怪。 var1
var2
的计数是否只是var2
中值的频率,除非缺少值?我假设当时缺少值。
egen var3 = count(var1), by(var2) /* creates var3 as the total observations in
var1, for each category in var2 */
所以我们在这里按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[])
我们现在可以将结果合并回我们的数据框,以复制egen
所做的事情。
foo <- merge(foo, v3obs, by="var2", type="left")
您也可以使用for
循环执行此操作,循环遍历行,子集var3
获取var2
的值,并填写计数非缺失观察值。这可能更容易阅读,但效率较低。我可能还有更好的方法,我不知道,by
对我来说不是那么直观(我也来自Stata背景)所以我一般都试图避免它。