这适用于您的示例:
clear
input num1 num2 num3 num4 num5 num6
1 2 . 2 4 .
. . . 3 4 4
. . 3 4 1 .
. 2 . 2 1 .
end
egen all = concat(num*)
replace all = subinstr(all, ".", "", .)
compress all
count if all != ""
local j = 1
quietly while r(N) > 0 {
gen NUM`j' = real( substr(all, 1, 1) )
replace all = substr(all, 2, .)
local ++j
count if all != ""
}
drop all
list num* NUM*
+---------------------------------------------------------------------+
| num1 num2 num3 num4 num5 num6 NUM1 NUM2 NUM3 NUM4 |
|---------------------------------------------------------------------|
1. | 1 2 . 2 4 . 1 2 2 4 |
2. | . . . 3 4 4 3 4 4 |
3. | . . 3 4 1 . 3 4 1 |
4. | . 2 . 2 1 . 2 2 1 |
+---------------------------------------------------------------------+
编辑:这会在旧变量旁边创建新变量。然后由您决定是否使用旧的drop 和新的rename。
除了您的示例之外,该主题还提出了各种问题,包括
-
您的数据布局(有人说是结构或格式)是否适合您的目的。例如,如果您的数据集确实是面板或纵向数据,那么在 Stata 中通常更可取的是长布局。为此,您需要reshape long。
-
此方法的内存和速度方面的比较与第一个基于reshape long 的方法(如果原始布局被认为是必要的,则为最终的reshape wide)。比较可能以 OP 的数据集为特征(以及其他类似形式但大小不同的数据集,因为此处发布的主要目的是其他人可能有类似的问题)。
人们似乎经常抱怨reshape 的速度,但抛开猜测和八卦,证据会很有趣。
编辑 2020 年 3 月 30 日,我建议这是一个更好的解决方案。
clear
input num1 num2 num3 num4 num5 num6
1 2 . 2 4 .
. . . 3 4 4
. . 3 4 1 .
. 2 . 2 1 .
end
egen NUM = concat(num?), p(" ")
replace NUM = subinstr(NUM, ".", "", .)
split NUM, destring
list NUM?
+---------------------------+
| NUM1 NUM2 NUM3 NUM4 |
|---------------------------|
1. | 1 2 2 4 |
2. | 3 4 4 . |
3. | 3 4 1 . |
4. | 2 2 1 . |
+---------------------------+