我有一个不平衡的大型数据集,每个观察点可以采用多个字符串值,每个值存储在一个单独的变量中:
obs year var1 var2 var3 newval
1 1990 str1 str2 str3 3
1 1991 str1 str4 str5 2
2 1990 str3 str4 2
2 1991 str4 str5 1
2 1993 str3 str5 0
2 1994 str7 1
在每个时间点和每次观察时,我需要计算字符串值是否为“新”。这意味着他们没有出现在前几年观察所采取的价值观中。
我应该如何在Stata中解决这个问题?
谢谢。
答案 0 :(得分:1)
这可能是一种更优雅的方式。
主要思想是我首先重塑数据并按顺序计算每个字符串的出现次数。重塑使这变得更容易。然后我将聚合崩溃,但只计算每个字符串出现的第一个实例。然后我将重新加入您的原始数据。
#delimit;
preserve;
tempfile newval;
reshape long var, i(obs year) j(s); // stack all the vars on top of each other
bys obs var (year): gen n=_n if !missing(var); // number the appearance of each string in chronological order
replace n=0 if n>1 & !missing(n); // only count the first instance
collapse (sum) mynewval=n, by(obs year); // add up the counts
save `newval';
restore;
merge 1:1 obs year using `newval', nogen;
compare newval mynewval;
答案 1 :(得分:1)
此问题也发布在Statalist上。这是我的答案。除非问题以两个或更多文件开头,否则我倾向于不使用merge
。
clear
input obs yr str4 var1 str4 var2 str4 var3
1 90 str1 str2 str3
1 91 str1 str4 str5
2 90 str3 str4
2 91 str4 str5
2 93 str3 str5
2 94 str7
end
reshape long var , i(obs yr) j(which)
bysort obs var (yr) : gen new = _n == 1 & !missing(var)
bysort obs yr : replace new = sum(new)
by obs yr : replace new = new[_N]
reshape wide var, i(obs yr) j(which)
(更多)进一步的评论主要关注效率,这意味着速度而不是空间。 (存储空间可以咬海报。)
如果没有重组,这里使用reshape
,问题是三重循环:超过标识符,超过每个标识符和变量的观察。可能两个外环可以折叠成一个。但是在Stata中,观察的显式循环通常很慢。
使用Dimitriy和我自己提出的重组解决方案,by:
操作直接编译代码并且相对较快:reshape
是解释代码并需要文件操作,因此可能很慢。另一方面,reshape
可以用一些经验快速写下来,并且值得通过经验带来的reshape
获得流畅性。除了reshape
和手动输入的帮助之外,请参阅我在http://www.stata.com/support/faqs/data-management/problems-with-reshape/撰写的reshape
常见问题解答
另一个考虑因素是你想用这种数据集做什么。如果存在其他类似特征的问题,那么reshape
生成的结构通常会更容易,因此保持该结构将是一个好主意。