构造和修改变量

先查看各命令展开的示例,再按需展开其他选项及 R 实现。改写代码前,请阅读适用条件及差异说明。

ceil

向上取整

Stata

generate y = ceil(x)

R 包:base

mutate(data, y = ceiling(x))

clonevar

克隆一个变量

Stata

clonevar x2 = x

R 包:dplyr

mutate(data, x2 = x)

与 Stata 有差异 mutate(x2 = x) 复制 R 向量和属性,但不完整复现 Stata clonevar 的变量特征及注释。

collapse

用统计量分组描述若干变量,并替换原数据

Stata

collapse (mean) x1 x2, by(group)

R 包:dplyr

summarise(data, across(c(x1, x2), ~ mean(.x, na.rm = TRUE)), .by = group)

与 Stata 有差异 像 collapse 一样替换数据需要赋值:data <- summarise(…)。summ(data, x1, x2, .by = group) 则只显示汇总表。 R 保留缺失分组键;Stata tabstat by() 和 tabulate summarize() 默认排除缺失分组类别。应核对分组样本。

另有 1 个示例及替代实现

对不同变量使用不同的统计量

Stata

collapse (count) n = x (sum) total = y, by(group)

R 包:dplyr

summarise(data, n = sum(!is.na(x)), total = sum(y, na.rm = TRUE), .by = group)

cond

按条件取不同的值

Stata

generate y = cond(x > 0, 1, 0)

R 包:dplyr

mutate(data, y = if_else(x > 0, 1, 0))

与 Stata 有差异 x 缺失时,Stata 的 cond() 取第一个值(缺失值视为很大);if_else() 返回 NA。 Stata 数值缺失比较时大于所有有限数;R 比较返回 NA。应先明确处理缺失,再使用条件。

destring

把文本变量转换成数值变量

Stata

destring str_x, generate(num_x)

R 包:tidystata

mutate(data, num_x = destring(str_x))

与 Stata 有差异 不是数字的文本会变为 NA 并给出警告,相当于 force 选项。destring(str_x, ignore = “kg”) 会先删除这些字符,相当于 ignore(),因此 “10 kg” 得到 10。 无效数字文本在此变为 NA 并警告;Stata destring 未指定 force 时拒绝转换含此类文本的变量。

egen

根据分位数,将连续变量均等地分成类别变量

Stata

egen bins = cut(x), group(10)

R 包:tidystata

mutate(data, bins = xtile(x, 10))

与 Stata 有差异 egen cut(), group() 有自己的分组规则;xtile() 遵循 Stata 的 xtile,这是分位数分组的常用命令。

标记每组的第一行

Stata

egen first = tag(group)

R 包:tidystata

mutate(data, first = is_first(group))

与 Stata 有差异 返回 TRUE/FALSE;与 Stata 相同,分组变量缺失的行为 FALSE,除非设置 .missing = TRUE。 R 结果为逻辑值 TRUE/FALSE,而非数值 1/0;需要一致存储类型时使用 as.integer()。

给组编号

Stata

egen id = group(g1 g2)

R 包:dplyr

data |> group_by(g1, g2) |> mutate(id = cur_group_id()) |> ungroup()

与 Stata 有差异 cur_group_id() 也为缺失键分组编号;egen group() 未指定 missing 时排除这些行。字符串排序也可能改变编号顺序。

通过计算函数生成新变量

Stata

egen x_avg = mean(x)

R 包:dplyr

mutate(data, x_avg = mean(x, na.rm = TRUE))

与 Stata 有差异 R 函数默认不忽略缺失值,需要 na.rm = TRUE;Stata 的 egen 会自动忽略。 全缺失组的 mean(…, na.rm = TRUE) 返回 NaN;Stata egen mean() 返回数值缺失。需要区分时应统一 NaN。

多个变量逐行求和

Stata

egen x_sum = rowtotal(x1-x5)

R 包:tidystata

mutate(data, x_sum = row_sum(x1:x5))
另有 24 个示例及替代实现

分组中位数

Stata

bysort group: egen med = median(x)

R 包:dplyr

mutate(data, med = median(x, na.rm = TRUE), .by = group)

分组最小值

Stata

bysort group: egen mn = min(x)

R 包:dplyr

dplyr::mutate(data, mn = if (all(is.na(x))) NA_real_ else min(x, na.rm = TRUE), .by = group)

与 Stata 有差异 全缺失组返回NA,不对空集合调用min()。 全缺失组的 R max/min 在 na.rm = TRUE 时返回 -Inf/Inf 并警告;Stata egen max()/min() 返回缺失。

分组最大值

Stata

bysort group: egen mx = max(x)

R 包:dplyr

dplyr::mutate(data, mx = if (all(is.na(x))) NA_real_ else max(x, na.rm = TRUE), .by = group)

与 Stata 有差异 全缺失组返回NA,不对空集合调用max()。 全缺失组的 R max/min 在 na.rm = TRUE 时返回 -Inf/Inf 并警告;Stata egen max()/min() 返回缺失。

每组非缺失值的个数

Stata

bysort group: egen n = count(x)

R 包:dplyr

mutate(data, n = sum(!is.na(x)), .by = group)

分组标准差

Stata

bysort group: egen s = sd(x)

R 包:dplyr

mutate(data, s = sd(x, na.rm = TRUE), .by = group)

分组求和

Stata

bysort group: egen tot = total(x)

R 包:dplyr

mutate(data, tot = sum(x, na.rm = TRUE), .by = group)

分组计算统计量

Stata

bysort group: egen x_avg = mean(x)

R 包:dplyr

mutate(data, x_avg = mean(x, na.rm = TRUE), .by = group)

与 Stata 有差异 全缺失组的 mean(…, na.rm = TRUE) 返回 NaN;Stata egen mean() 返回数值缺失。需要区分时应统一 NaN。

根据给定的切点分组

Stata

egen bins = cut(x), at(0(10)100)

R 包:base

mutate(data, bins = cut(x, breaks = seq(0, 100, 10), right = FALSE))

与 Stata 有差异 right = FALSE 使每个区间包含下限,与 egen cut() 一致。cut_length(x, 10) 则把取值范围等宽地分成 10 组。 cut() 返回带区间标签的因子;egen cut() 即使区间开闭一致,仍存储数值下界。

多个变量中第一个非缺失值

Stata

egen first = rowfirst(x1-x5)

R 包:dplyr

mutate(data, first = coalesce(x1, x2, x3, x4, x5))

把多个变量拼接成一个字符串

Stata

egen id = concat(a b), punct(_)

R 包:base

mutate(data, id = paste(a, b, sep = "_"))

与 Stata 有差异 paste() 将 NA 转成文本 “NA”;egen concat() 使用 Stata 缺失值及数值显示规则。

多个变量中最后一个非缺失值

Stata

egen last = rowlast(x1-x5)

R 包:dplyr

mutate(data, last = coalesce(x5, x4, x3, x2, x1))

计算等于某个值的变量个数

Stata

egen n9 = anycount(x1-x5), values(9)

R 包:dplyr

mutate(data, n9 = rowSums(across(x1:x5, ~ .x %in% 9)))

占总数的百分比

Stata

egen p = pc(x)

R 包:tidystata

mutate(data, p = pc(x))

pc(x, prop = TRUE) 给出比例,即 prop 选项。

排序(相同取值取平均秩)

Stata

egen r = rank(x)

R 包:base

mutate(data, r = rank(x, na.last = "keep"))

rank() 与 egen rank() 一样给相同取值平均秩;dplyr::min_rank() 则给最小秩。

生成循环序列

Stata

egen s = seq(), from(1) to(3)

R 包:dplyr

mutate(data, s = rep_len(1:3, n()))

多个变量逐行求均值

Stata

egen x_avg = rowmean(x1-x5)

R 包:tidystata

mutate(data, x_avg = row_mean(x1:x5))

多个变量逐行求最大值

Stata

egen x_max = rowmax(x1-x5)

R 包:tidystata

mutate(data, x_max = row_max(x1:x5))

多个变量逐行求中位数

Stata

egen x_med = rowmedian(x1-x5)

R 包:tidystata

mutate(data, x_med = row_median(x1:x5))

逐行计算缺失值个数

Stata

egen x_mi = rowmiss(x1-x5)

R 包:tidystata

mutate(data, x_mi = row_miss(x1:x5))

多个变量逐行求最小值

Stata

egen x_min = rowmin(x1-x5)

R 包:tidystata

mutate(data, x_min = row_min(x1:x5))

逐行计算非缺失值个数

Stata

egen x_n = rownonmiss(x1-x5)

R 包:tidystata

mutate(data, x_n = row_non_miss(x1:x5))

每行不同取值的个数

Stata

egen x_nv = rownvals(x1-x5)

R 包:tidystata

mutate(data, x_nv = row_nvals(x1:x5))

来自 egenmore(SSC)。默认忽略缺失值;.missing = TRUE 相当于 missing 选项。

多个变量逐行求标准差

Stata

egen x_sd = rowsd(x1-x5)

R 包:tidystata

mutate(data, x_sd = row_sd(x1:x5))

标准化变量

Stata

egen z = std(x)

R 包:tidystata

mutate(data, z = std(x))

base R:as.vector(scale(x))。加 .by = g 即 by g: egen。

floor

向下取整

Stata

generate y = floor(x)

R 包:base

mutate(data, y = floor(x))

format

以两位小数显示数值

Stata

format x %9.2f

R 包:base

mutate(data, x_text = sprintf("%.2f", x))

R 不改变存储的数值,只在显示时设定格式,例如 round(x, 2) 或 sprintf()。

generate

生成新变量

Stata

generate x2 = x^2

R 包:dplyr

mutate(data, x2 = x^2)

需要把结果赋值回去才能保留:data <- mutate(data, …)。R 不区分 generate 和 replace。

另有 8 个示例及替代实现

生成总行数变量

Stata

generate N = _N

R 包:dplyr

mutate(data, N = n())

加上 .by = group 即为每组的行数,相当于 bysort group: generate N = _N。

生成第几行变量

Stata

generate n = _n

R 包:dplyr

mutate(data, n = row_number())

两个日期之间的天数

Stata

generate days = d2 - d1

R 包:base

mutate(data, days = as.numeric(d2 - d1))

根据条件生成逻辑变量/虚拟变量

Stata

generate dummy = (x1 == 1 & x2 == 2)

R 包:dplyr

dplyr::mutate(data, dummy = as.integer(x1 %in% 1 & x2 %in% 2))

与 Stata 有差异 Stata的数值等式对缺失值返回假;%in%使任一输入缺失时虚拟变量为零。 R 结果为逻辑值 TRUE/FALSE,而非数值 1/0;需要一致存储类型时使用 as.integer()。

生成滞后变量

Stata

generate lag_x = x[_n-1]

R 包:dplyr

mutate(data, lag_x = lag(x))

这与 x[_n-1] 一样按行移动,不考虑时间上的间隔。面板数据的滞后请查看 L.。

生成前定变量

Stata

generate lead_x = x[_n+2]

R 包:dplyr

mutate(data, lead_x = lead(x, 2))

根据条件生成新变量

Stata

generate x2 = x^2 if x > 0

R 包:dplyr

mutate(data, x2 = if_else(x > 0, x^2, NA))

Stata 中缺失值大于任何数,所以缺失的 x 满足 x > 0;R 中该条件为 NA,结果也为 NA。

根据位置生成新变量

Stata

generate x2 = x^2 in 11/20

R 包:dplyr

mutate(data, x2 = if_else(row_number() %in% 11:20, x^2, NA))

inlist

x 是否等于列出的某个值

Stata

generate y = inlist(x, 1, 3, 5)

R 包:base

mutate(data, y = x %in% c(1, 3, 5))

与 Stata 有差异 x 缺失时 %in% 返回 FALSE,与 inlist() 一致。 R 返回逻辑指示值,而 Stata generate 存储数值 1/0;需要一致存储类型时使用 as.integer()。

inrange

x 是否在某个范围内

Stata

generate y = inrange(x, 1, 5)

R 包:dplyr

mutate(data, y = between(x, 1, 5))

与 Stata 有差异 x 缺失时 between() 返回 NA,而 Stata 的 inrange() 返回 0。

ln

自然对数

Stata

generate y = ln(x)

R 包:base

mutate(data, y = log(x))

与 Stata 有差异 log10() 对应 Stata 的 log10()。R 中 log(0) 为 -Inf,而不是缺失值。 R log(0) 返回 -Inf,负输入返回 NaN 并警告;Stata ln() 对这些无效输入返回数值缺失。

missing

是否为缺失值

Stata

generate m = missing(x)

R 包:base

mutate(data, m = is.na(x))

与 Stata 有差异 R 返回逻辑指示值,而 Stata generate 存储数值 1/0;需要一致存储类型时使用 as.integer()。

mvdecode

把缺失值代码改为缺失值

Stata

mvdecode x, mv(-9)

R 包:tidystata

mutate(data, x = mvdecode(x, -9))

mvdecode(x, c(-8, -9)) 可同时处理多个代码,如 mv(-8 -9)。

mvencode

把缺失值改为特定取值

Stata

mvencode x, mv(-9)

R 包:tidystata

mutate(data, x = mvencode(x, -9))

pctile

分位数切点

Stata

pctile p = x, nquantiles(4)

R 包:tidystata

summ(data, x, .stat = c("p25", "median", "p75"))

与 Stata 有差异 summ() 使用 Stata 的百分位数规则。quantile(x, type = 2) 与之接近,但会把某些整数位置(如 100 * 0.3)当作非整数。 summ() 在汇总表中返回百分位数;pctile 创建包含切点的数据列。

recast

更改存储类型

Stata

recast double x

R 包:base

mutate(data, x = as.double(x))

R 自动选择存储类型,因此也不需要 compress。

recode

重编码变量

Stata

recode x (1/5 = 1) (6/10 = 2) (11/15 = 3) (else = .), generate(x3g)

R 包:dplyr

mutate(data, x3g = case_when(between(x, 1, 5) ~ 1, between(x, 6, 10) ~ 2, between(x, 11, 15) ~ 3))

不满足任何条件的取值为 NA,相当于 Stata 的 else = .。

另有 1 个示例及替代实现

把某个取值改为缺失值

Stata

recode x (9 = .)

R 包:dplyr

mutate(data, x = na_if(x, 9))

rename

重命名变量

Stata

rename x x2

R 包:dplyr

rename(data, x2 = x)

注意顺序:新名字 = 旧名字。

另有 4 个示例及替代实现

同时重命名多个变量

Stata

rename (a b) (c d)

R 包:dplyr

rename(data, c = a, d = b)

给所有变量名加后缀

Stata

rename * *_old

R 包:dplyr

rename_with(data, ~ paste0(.x, "_old"))

批量重命名变量到小写

Stata

rename *, lower

R 包:dplyr

rename_with(data, tolower)

把部分变量名改为大写

Stata

rename x*, upper

R 包:dplyr

rename_with(data, toupper, starts_with("x"))

replace

修改旧变量

Stata

replace x = x^2

R 包:dplyr

mutate(data, x = x^2)
另有 2 个示例及替代实现

根据条件修改旧变量

Stata

replace x = x^2 if x > 0

R 包:dplyr

mutate(data, x = if_else(x > 0, x^2, x))

与 Stata 有差异 Stata 数值缺失比较时大于所有有限数;R 比较返回 NA。应先明确处理缺失,再使用条件。

根据位置修改旧变量

Stata

replace x = x^2 in 11/20

R 包:dplyr

mutate(data, x = if_else(row_number() %in% 11:20, x^2, x))

rnormal

正态分布随机数

Stata

generate z = rnormal()

R 包:stats

mutate(data, z = rnorm(n()))

与 Stata 有差异 R 与 Stata 使用不同随机数流;相同数值种子不会复现相同随机数或抽样行。

round

四舍五入

Stata

generate y = round(x, 0.1)

R 包:base

mutate(data, y = round(x, 1))

与 Stata 有差异 R 的第二个参数是小数位数。R 对 .5 采用四舍六入五成双(round(0.5) 为 0);Stata 则向上取整。

runiform

均匀分布随机数

Stata

generate u = runiform()

R 包:stats

mutate(data, u = runif(n()))

与 Stata 有差异 R 与 Stata 使用不同随机数流;相同数值种子不会复现相同随机数或抽样行。

sum

累计求和

Stata

generate cs = sum(x)

R 包:dplyr

mutate(data, cs = cumsum(coalesce(x, 0)))

Stata 的 sum() 函数把缺失值当作 0,因此这里用 coalesce(x, 0)。

tabulate

生成(类别变量)x 所有取值的虚拟变量

Stata

tabulate x, generate(x_)

R 包:tidystata

as_dummy(data, x)

与 Stata 有差异 as_dummy(data, x, .names = “index”) 像 Stata 一样把新列编号为 x_1、x_2……。也可用 fastDummies::dummy_cols(data, “x”)。 as_dummy() 默认按取值命名列;.names = “index” 可生成 Stata 式编号后缀。还须核对缺失类别指示列规则。

tostring

把数值变量转换成文本变量

Stata

tostring num_x, generate(str_x)

R 包:tidystata

mutate(data, str_x = tostring(num_x))

与 Stata 有差异 带标签的变量保留数值代码;decode() 则返回数值标签。 格式和保留精度可能与 Stata tostring 不同;需要精确文本或往返精度时须明确格式。

winsor2

在第 1 和第 99 百分位缩尾

Stata

winsor2 x, cuts(1 99)

R 包:datawizard

mutate(data, x_w = datawizard::winsorize(x, threshold = 0.01))

与 Stata 有差异 datawizard 使用 R 分位数切点,winsor2 使用 Stata 百分位规则;小样本和并列值可能产生不同截尾边界。

xtile

根据分位数分组

Stata

xtile q = x, nquantiles(4)

R 包:tidystata

mutate(data, q = xtile(x, 4))

xtile() 遵循 Stata 的规则,相同取值总在同一组。

另有 1 个示例及替代实现

根据加权分位数分组

Stata

xtile q = x [aweight = w], nquantiles(4)

R 包:tidystata

mutate(data, q = xtile(x, 4, wt = w))