数据管理

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

append

追加列集合不同的数据表

Stata

append using other.dta

R 包:dplyr

data <- dplyr::bind_rows(data,other)

固定流程示例;更改时需同时调整对象名与列名。

另有 2 个示例及替代实现

仅追加附表所选列

Stata

append using other.dta, keep(x)

R 包:dplyr

data <- dplyr::bind_rows(data,other['x'])

追加多个数据集并记录来源

Stata

append using second.dta third.dta, generate(source)

R 包:dplyr

data <- dplyr::bind_rows(list('0'=data,'1'=second,'2'=third),.id='source'); data$source <- as.integer(data$source)

assertnested

验证每个编号对应的组属性恒定

Stata

assertnested id, within(g)

R 包:base

stopifnot(all(vapply(split(data$g,data$id),function(z) length(unique(z))==1L,logical(1))))

验证每个区只属于一个地区

Stata

assertnested region district

R 包:base

stopifnot(all(vapply(split(data$region,data$district),function(z) length(unique(z))==1L,logical(1))))

cf

定位指定列取值不同的行

Stata

cf x using other.dta, verbose

R 包:base

which(data$x != other$x | xor(is.na(data$x),is.na(other$x)))

此流程仅检查 x;完整逐列报告需对各列进行比较。

验证两个数据表指定列的值一致

Stata

cf x y using other.dta

R 包:base

stopifnot(identical(unname(as.matrix(data[c('x','y')])),unname(as.matrix(other[c('x','y')]))))

与 Stata 有差异 按行序比较已读入的 other 数据表;与 cf 一样忽略元数据。

clonevar

复制列及其属性

Stata

clonevar copy = x

R 包:base

data$copy <- data$x

codebook

查看非缺失数、不同值数与范围

Stata

codebook x, compact

R 包:base

c(nonmissing=sum(!is.na(data$x)),unique=length(unique(data$x[!is.na(data$x)])),min=min(data$x,na.rm=TRUE),max=max(data$x,na.rm=TRUE))

与 Stata 有差异 提供数值变量概览的一部分;不复制 Stata 变量标签与格式报告。

compare

比较取值大小与缺失模式

Stata

compare x y

R 包:base

c(less=sum(data$x<data$y,na.rm=TRUE),equal=sum(data$x==data$y,na.rm=TRUE),greater=sum(data$x>data$y,na.rm=TRUE),x_missing_only=sum(is.na(data$x)&!is.na(data$y)),both_missing=sum(is.na(data$x)&is.na(data$y)))

与 Stata 有差异 给出主要比较计数,不复制 Stata 的格式化差值摘要。

比较指定子样本中的取值大小

Stata

compare x y if g == 1

R 包:base

with(subset(data,g==1),table(sign(x-y),useNA='ifany'))

与 Stata 有差异 仅返回大小关系计数;差值幅度需另行汇总。

compress

将安全范围内整值改存 R 整数

Stata

compress x

R 包:base

stopifnot(all(is.na(data$x) | (data$x==trunc(data$x) & abs(data$x)<=.Machine$integer.max))); data$x <- as.integer(data$x)

仅手动优化整值存储。R 无 Stata 的 byte/int 存储类型或通用 compress 对应命令。

count

统计指定列均完整的行数

Stata

count if !missing(x, y)

R 包:base

sum(stats::complete.cases(data[c('x','y')]))
另有 3 个示例及替代实现

统计缺失值数

Stata

count if missing(x)

R 包:base

sum(is.na(data$x))

统计超过阈值的非缺失值数

Stata

count if x > 2 & x < .

R 包:base

sum(data$x > 2,na.rm=TRUE)

统计指定行区间的行数

Stata

count in 2/5

R 包:base

nrow(data[2:5,,drop=FALSE])

固定流程示例;更改时需同时调整对象名与列名。

cross

创建两个数据集的笛卡尔积

Stata

cross using other.dta

R 包:dplyr

data <- dplyr::cross_join(data,other)

固定流程示例;更改时需同时调整对象名与列名。

cumul

生成变量的经验累积分布

Stata

cumul x, generate(c)

R 包:dplyr

data$c <- dplyr::row_number(data$x) / sum(!is.na(data$x))

与 Stata 有差异 缺失值仍为缺失,且不计入分母。Stata 默认对相同取值按任意顺序赋予不同的累积值,R 按行顺序处理相同取值。权重及 by() 需另行按组或加权计算。

另有 1 个示例及替代实现

相同取值共享累积值的经验累积分布

Stata

cumul x, generate(c) equal

R 包:dplyr

data$c <- dplyr::cume_dist(data$x)

相同取值共享最大的累积比例,与 ecdf(x)(x) 相同;缺失值仍为缺失。

datasignature

验证数据匹配已保存的 R 签名

Stata

datasignature confirm

R 包:base

stopifnot(identical(signature,serialize(data,NULL,version=2)))

R 特有的字节比较;不兼容 Stata 的 .dtasig 文件。

保存 R 序列化结果供后续比较

Stata

datasignature set

R 包:base

signature <- serialize(data,NULL,version=2)

保存 R 特有的序列化快照;不使用 Stata 校验算法,且包含 R 元数据。

describe

查看所选列的存储类型

Stata

describe x y

R 包:base

vapply(data[c('x','y')],typeof,character(1))
另有 1 个示例及替代实现

简洁查看数据维度

Stata

describe, short

R 包:base

c(observations=nrow(data),variables=ncol(data))

固定流程示例;更改时需同时调整对象名与列名。

destring

解析干净的数值字符串

Stata

destring s, generate(x)

R 包:base

data$x <- as.numeric(data$s)
另有 3 个示例及替代实现

解析以逗号为小数点的字段

Stata

destring s, generate(x) dpcomma

R 包:base

data$x <- as.numeric(sub(',','.',data$s,fixed=TRUE))

解析带千位逗号的数值

Stata

destring s, generate(x) ignore(",")

R 包:base

data$x <- as.numeric(gsub(',','',data$s,fixed=TRUE))

将百分比文本转换为比例

Stata

destring s, generate(x) percent

R 包:base

data$x <- as.numeric(sub('%$','',data$s))/100

drop

删除一个类别的行

Stata

drop if g == 2

R 包:base

data <- data[data$g != 2, , drop=FALSE]
另有 5 个示例及替代实现

删除指定值缺失的行

Stata

drop if missing(x)

R 包:base

data <- data[!is.na(data$x), , drop=FALSE]

删除指定列中存在缺失的行

Stata

drop if missing(x, y)

R 包:tidyr

data <- tidyr::drop_na(data, x, y)

删除低值并保留缺失行

Stata

drop if x <= 2

R 包:dplyr

data <- dplyr::filter(data, is.na(x) | x > 2)

与 Stata 有差异 Stata 数值缺失大于有限值;显式 is.na 分支保留这些行。

按位置删除连续行

Stata

drop in 2/4

R 包:base

data <- data[-(2:4), , drop=FALSE]

固定流程示例;更改时需同时调整对象名与列名。

删除指定列

Stata

drop s y

R 包:base

data <- data[setdiff(names(data),c('s','y'))]

ds

查找排除列表以外的列名

Stata

ds id g, not

R 包:base

setdiff(names(data),c('id','g'))
另有 2 个示例及替代实现

查找数值列名

Stata

ds, has(type numeric)

R 包:base

names(data)[vapply(data,is.numeric,logical(1))]

固定流程示例;更改时需同时调整对象名与列名。

查找字符列名

Stata

ds, has(type string)

R 包:base

names(data)[vapply(data,is.character,logical(1))]

固定流程示例;更改时需同时调整对象名与列名。

duplicates

每个重复键仅保留首条观测

Stata

duplicates drop id, force

R 包:base

data <- data[!duplicated(data$id),,drop=FALSE]
另有 3 个示例及替代实现

查看重复键的全部组成员

Stata

duplicates list id

R 包:base

data[duplicated(data$id)|duplicated(data$id,fromLast=TRUE),,drop=FALSE]

汇总重复次数、观测数与重复盈余

Stata

duplicates report id

R 包:base

counts <- as.integer(table(data$id)); data.frame(copies=sort(unique(counts)),observations=vapply(sort(unique(counts)),function(k) sum(counts[counts==k]),integer(1)),surplus=vapply(sort(unique(counts)),function(k) sum(counts==k)*(k-1L),integer(1)))

用重复盈余数标记每个组成员

Stata

duplicates tag id, generate(dup)

R 包:dplyr

data <- dplyr::mutate(data,dup=dplyr::n()-1L,.by=id)

egen

保留行数并添加组均值

Stata

bysort g: egen z = mean(x)

R 包:dplyr

data <- dplyr::mutate(data,z=mean(x,na.rm=TRUE),.by=g)
另有 30 个示例及替代实现

保留行数并添加组总和

Stata

bysort g: egen z = total(x)

R 包:dplyr

data <- dplyr::mutate(data,z=sum(x,na.rm=TRUE),.by=g)

逐行统计多列中指定值出现次数

Stata

egen z = anycount(x y), values(2 4)

R 包:base

data$z <- rowSums(cbind(data$x %in% c(2,4),data$y %in% c(2,4)))

逐行标记多列是否含指定值

Stata

egen z = anymatch(x y), values(2 4)

R 包:base

data$z <- as.integer(data$x %in% c(2,4) | data$y %in% c(2,4))

拼接数值列与字符串列

Stata

egen z = concat(g s), punct("-")

R 包:base

data$z <- paste(data$g,ifelse(is.na(data$s),'',data$s),sep='-')

与 Stata 有差异 将 R 的 NA 字符串视为 Stata 空串;本例使用简单十进制数值格式。

在一列中重复非缺失计数

Stata

egen z = count(x)

R 包:base

data$z <- sum(!is.na(data$x))

分箱并用左端点标记箱

Stata

egen z = cut(x), at(0,3,7)

R 包:base

data$z <- as.numeric(as.character(cut(data$x,breaks=c(0,3,7),right=FALSE,labels=c(0,3))))

标记两列是否不同

Stata

egen z = diff(x y)

R 包:base

data$z <- as.integer(!(data$x==data$y | (is.na(data$x)&is.na(data$y)))); data$z[xor(is.na(data$x),is.na(data$y))] <- 1L

与 Stata 有差异 显式处理普通缺失;Stata 扩展缺失类别需单独比较。

生成首个非缺失值常量列

Stata

egen z = firstnm(x)

R 包:base

data$z <- data$x[which(!is.na(data$x))[1]]

为多个分组键组合编码

Stata

egen z = group(g s)

R 包:base

data$z <- as.integer(interaction(data$g,data$s,drop=TRUE,lex.order=TRUE)); data$z[is.na(data$s) | data$s==''] <- NA_integer_

与 Stata 有差异 组合编号用于识别组;具体数值编码与字符串排序可能不同于 Stata。

生成四分位距常量列

Stata

egen z = iqr(x)

R 包:base

data$z <- diff(stats::quantile(data$x,c(.25,.75),na.rm=TRUE,type=2))

与 Stata 有差异 使用 R 的 type 2 分位数以对应 Stata 默认经验百分位规则。

生成最后一个非缺失值常量列

Stata

egen z = lastnm(x)

R 包:base

data$z <- utils::tail(c(NA_real_, data$x[!is.na(data$x)]), 1)

在一列中重复最大值

Stata

egen z = max(x)

R 包:base

data$z <- if (all(is.na(data$x))) NA_real_ else max(data$x, na.rm=TRUE)

在一列中重复均值

Stata

egen z = mean(x)

R 包:base

data$z <- mean(data$x,na.rm=TRUE)

在一列中重复中位数

Stata

egen z = median(x)

R 包:base

data$z <- stats::median(data$x,na.rm=TRUE)

在一列中重复最小值

Stata

egen z = min(x)

R 包:base

data$z <- if (all(is.na(data$x))) NA_real_ else min(data$x, na.rm=TRUE)

将取值转换为列总和的百分比

Stata

egen z = pc(x)

R 包:base

data$z <- 100*data$x/sum(data$x,na.rm=TRUE)

要求非缺失值总和非零;这是份额计算,不是调查估计。

生成指定经验百分位常量列

Stata

egen z = pctile(x), p(25)

R 包:base

data$z <- as.numeric(stats::quantile(data$x,.25,na.rm=TRUE,type=2))

与 Stata 有差异 使用 R 的 type 2 分位数以对应 Stata 默认经验百分位规则。

对非缺失值排序并对并列取平均秩

Stata

egen z = rank(x)

R 包:base

data$z <- rank(data$x,na.last='keep',ties.method='average')

最高值排首且并列使用竞赛秩

Stata

egen z = rank(x), field

R 包:base

data$z <- rank(-data$x,na.last='keep',ties.method='min')

逐行取可用最大值

Stata

egen z = rowmax(x y)

R 包:base

data$z <- pmax(data$x,data$y,na.rm=TRUE)

对多列可用值逐行求均值

Stata

egen z = rowmean(x y)

R 包:base

data$z <- rowMeans(data[c('x','y')],na.rm=TRUE); data$z[is.nan(data$z)] <- NA_real_

逐行取可用最小值

Stata

egen z = rowmin(x y)

R 包:base

data$z <- pmin(data$x,data$y,na.rm=TRUE)

逐行统计缺失单元数

Stata

egen z = rowmiss(x y)

R 包:base

data$z <- rowSums(is.na(data[c('x','y')]))

逐行统计非缺失单元数

Stata

egen z = rownonmiss(x y)

R 包:base

data$z <- rowSums(!is.na(data[c('x','y')]))

对多列的可用值逐行求和

Stata

egen z = rowtotal(x y)

R 包:base

data$z <- rowSums(data[c('x','y')],na.rm=TRUE)

整行均缺失时行和返回缺失

Stata

egen z = rowtotal(x y), missing

R 包:base

data$z <- rowSums(data[c('x','y')],na.rm=TRUE); data$z[rowSums(!is.na(data[c('x','y')]))==0] <- NA_real_

在一列中重复样本标准差

Stata

egen z = sd(x)

R 包:base

data$z <- stats::sd(data$x,na.rm=TRUE)

使用样本标准差标准化

Stata

egen z = std(x)

R 包:base

data$z <- as.numeric(scale(data$x))

标记每组的首个非缺失观测

Stata

egen z = tag(g)

R 包:base

data$z <- as.integer(!is.na(data$g) & !duplicated(data$g))

在一列中重复总和

Stata

egen z = total(x)

R 包:base

data$z <- sum(data$x,na.rm=TRUE)

expandcl

复制完整组并赋予新的组编号

Stata

expandcl 2, cluster(g) generate(newg)

R 包:base

parts <- split(data,data$g); data <- do.call(rbind,lapply(seq_along(parts),function(k) do.call(rbind,lapply(1:2,function(j) transform(parts[[k]],newg=(k-1L)*2L+j)))))

与 Stata 有差异 验证组成员与复制次数;新编号具体取值及顺序可能不同于 Stata。

fcollapse

使用 ftools 公共辅助命令汇总均值

Stata

fcollapse (mean) z=x, by(g)

R 包:dplyr

data <- dplyr::summarise(data,z=mean(x,na.rm=TRUE),.by=g)

将 fcollapse 组汇总值附回原始行

Stata

fcollapse (mean) z=x, by(g) merge

R 包:dplyr

data <- dplyr::mutate(data,z=mean(x,na.rm=TRUE),.by=g)

组内全缺失时保留缺失总和

Stata

fcollapse (nansum) z=x, by(g)

R 包:dplyr

data <- dplyr::summarise(data,z=if(all(is.na(x))) NA_real_ else sum(x,na.rm=TRUE),.by=g)

fillin

补全缺失的类别键组合

Stata

fillin g h

R 包:tidyr

data <- tidyr::complete(data,g,h)

与 Stata 有差异 返回补全表但不带 Stata _fillin 标记;因子水平可能添加未使用的 R 类别。

另有 1 个示例及替代实现

标记类别补全时新插入的行

Stata

fillin g h

R 包:tidyr

data$`_fillin` <- 0L; data <- tidyr::complete(data,g,h,fill=list(`_fillin`=1L))

flevelsof

通过 ftools 类别辅助命令保存非缺失类别

Stata

flevelsof g, local(groups)

R 包:base

groups <- sort(unique(data$g[!is.na(data$g)]))

fmerge

执行已验证的 ftools 风格一对一合并

Stata

fmerge 1:1 id using other.dta, nogenerate

R 包:dplyr

data <- dplyr::full_join(data,other,by='id',relationship='one-to-one')

除非明确展示 update,非键列名需互不重复。dplyr 会为重名列添加后缀;普通 Stata merge 在匹配行保留主表取值,包括主表缺失值。

fralias

动态读取链接值而不保存复制列

Stata

fralias add score, from(link)

R 包:base

get_score <- function() lookup$score[match(data$id,lookup$id)]

R 访问函数流程,不是别名列:每次调用 get_score();修改应在 lookup 中进行。

frget

复制链接值时重命名

Stata

frget newscore=score, from(link)

R 包:base

data$newscore <- lookup$score[data$link]

这是复制取值的流程;不携带 Stata 框架链接与元数据。

通过已有表链接复制数值

Stata

frget score, from(link)

R 包:base

data$score <- lookup$score[data$link]

与 Stata 有差异 通过预先计算的链接复制值;Stata 显示格式与元数据在 R 中需显式复制。

frunalias

将动态查找值实体化为列

Stata

frunalias score

R 包:base

data$score <- lookup$score[match(data$id, lookup$id)]

将查询结果保存为普通 R 列快照。需要 data 和 lookup 两张表,具有匹配的 id 键及 lookup 中的 score 列;后续修改 lookup 不会改变该列。

gcollapse

按 gcollapse 流程汇总组均值

Stata

gcollapse (mean) z=x, by(g)

R 包:dplyr

data <- dplyr::summarise(data,z=mean(x,na.rm=TRUE),.by=g)

在汇总均值旁保留组原始行数

Stata

gcollapse (mean) z=x, by(g) freq(n)

R 包:dplyr

data <- dplyr::summarise(data,z=mean(x,na.rm=TRUE),n=dplyr::n(),.by=g)

将汇总组均值附回全部原始行

Stata

gcollapse (mean) z=x, by(g) merge

R 包:dplyr

data <- dplyr::mutate(data,z=mean(x,na.rm=TRUE),.by=g)

汇总各组缺失值数

Stata

gcollapse (nmissing) n=x, by(g)

R 包:dplyr

data <- dplyr::summarise(data,n=sum(is.na(x)),.by=g)

在完整数据中汇总各组不同值数

Stata

gcollapse (nunique) n=x, by(g)

R 包:dplyr

data <- dplyr::summarise(data,n=dplyr::n_distinct(x,na.rm=TRUE),.by=g)

与 Stata 有差异 本例取值完整;不声称缺失类别的处理一致。

gcontract

统计联合观测类别组合数

Stata

gcontract g h, freq(n)

R 包:dplyr

data <- dplyr::count(data,g,h,name='n')

使用 gcontract 创建类别频数与百分比

Stata

gcontract g, freq(n) percent(p)

R 包:dplyr

data <- dplyr::count(data,g,name='n'); data$p <- 100*data$n/sum(data$n)

gdistinct

分别统计多列不同值数

Stata

gdistinct g h

R 包:base

vapply(data[c('g','h')],function(z) length(unique(z[!is.na(z)])),integer(1))

联合统计完整组合的不同值数

Stata

gdistinct g h, joint

R 包:base

nrow(unique(data[stats::complete.cases(data[c('g','h')]),c('g','h')]))

gduplicates

每个复合键仅保留首行

Stata

gduplicates drop g h, force

R 包:base

data <- data[!duplicated(data[c('g','h')]),,drop=FALSE]

标记复合键的所有重复观测

Stata

gduplicates tag g h, generate(dup)

R 包:dplyr

data <- dplyr::mutate(data,dup=dplyr::n()-1L,.by=c(g,h))

gegen

为完整分组键组合创建编号

Stata

gegen groupid = group(g h)

R 包:base

data$groupid <- as.integer(interaction(data$g,data$h,drop=TRUE,lex.order=TRUE))

与 Stata 有差异 仅使用完整数值键;示例编号顺序按所示键的字典序排列。

标记各非缺失组的一条观测

Stata

gegen tag = tag(g)

R 包:base

data$tag <- as.integer(!is.na(data$g)&!duplicated(data$g))

通过 gegen 风格流程添加组均值

Stata

gegen z = mean(x), by(g)

R 包:dplyr

data <- dplyr::mutate(data,z=mean(x,na.rm=TRUE),.by=g)

generate

生成忽略缺失值的累计和

Stata

generate cumulative = sum(x)

R 包:base

data$cumulative <- cumsum(replace(data$x,is.na(data$x),0))

Stata 的 generate sum() 将缺失贡献视为零,与直接 cumsum() 不同。

另有 11 个示例及替代实现

在排序组内生成行号

Stata

bysort g (id): generate row = _n

R 包:dplyr

data <- dplyr::arrange(data,g,id); data <- dplyr::mutate(data,row=dplyr::row_number(),.by=g)

在组内计算累计和

Stata

bysort g (id): generate total = sum(x)

R 包:dplyr

data <- dplyr::arrange(data,g,id); data <- dplyr::mutate(data,total=cumsum(replace(x,is.na(x),0)),.by=g)

添加组内行数

Stata

bysort g: generate n = _N

R 包:dplyr

data <- dplyr::mutate(data,n=dplyr::n(),.by=g)

标记排序后各组的首个观测

Stata

bysort id (year): generate first = _n == 1

R 包:dplyr

{ data <- dplyr::arrange(data, id, year); dplyr::mutate(data, first = as.integer(dplyr::row_number() == 1L), .by = id) }

与 Stata 有差异 先按id和year排序,再在每个id中标记首行,包括id缺失组。R按输入顺序处理相同year;如需跨软件可复现的选择,应加入打破并列的变量。

生成保留缺失值的二元指标

Stata

generate byte high = x > 3 if x < .

R 包:base

data$high <- ifelse(is.na(data$x),NA_integer_,as.integer(data$x > 3))

生成非缺失指示变量

Stata

generate byte observed = !missing(x)

R 包:base

data$observed <- as.integer(!is.na(data$x))

计算变量平方并保留缺失

Stata

generate double z = x^2

R 包:base

data$z <- data$x^2

生成总行数常量列

Stata

generate n = _N

R 包:base

data$n <- nrow(data)

按行位置滞后一行

Stata

generate prior = x[_n-1]

R 包:dplyr

data$prior <- dplyr::lag(data$x)

与 Stata 有差异 按行位置移动;不涉及时间间隔或 tsset 语义。

生成行号

Stata

generate row = _n

R 包:base

data$row <- seq_len(nrow(data))

逐行相加并传播缺失

Stata

generate z = x + y

R 包:base

data$z <- data$x + data$y

getmata

将矩阵转换为具名数据列

Stata

getmata (x y)=X

R 包:base

data <- as.data.frame(X); names(data) <- c('x','y')

创建新 R 数据表,代替从独立 Mata 工作区导入;矩阵名 X 固定。

gisid

验证含普通缺失的复合键唯一性

Stata

gisid g h, missok

R 包:base

stopifnot(!anyDuplicated(data[c('g','h')]))

与 Stata 有差异 允许普通缺失作为键值;此处未表示 Stata 扩展缺失类别。

使用 gisid 验证编号唯一且完整

Stata

gisid id

R 包:base

stopifnot(!anyNA(data$id),!anyDuplicated(data$id))

glevelsof

列出不同的完整多列键

Stata

glevelsof g h

R 包:base

levels <- unique(data[c('g','h')]); levels <- levels[do.call(order,levels),,drop=FALSE]

与 Stata 有差异 返回键表而非空格分隔局部宏;本例键均无缺失。

使用 glevelsof 保存排序后的不同类别

Stata

glevelsof g, local(levels)

R 包:base

levels <- sort(unique(data$g[!is.na(data$g)]))

gquantiles

分配四个经验分位类别

Stata

gquantiles quartile=x, xtile nquantiles(4)

R 包:base

cuts <- stats::quantile(data$x,c(.25,.5,.75),type=2); data$quartile <- as.integer(cut(data$x,breaks=c(-Inf,cuts,Inf),right=TRUE))

与 Stata 有差异 使用非加权且互异有限值;显式采用 R type-2 阈值与右闭分箱。并列值可能使组大小不等。

返回指定经验百分位阈值

Stata

gquantiles x, _pctile percentiles(25 50 75)

R 包:base

stats::quantile(data$x,c(.25,.5,.75),type=2)

与 Stata 有差异 显式 R type-2 非加权百分位流程;不声称其他定义或加权结果数值一致。

greshape

使用 greshape 收集明确指定的宽格式列

Stata

greshape gather x1 x2, keys(measure) values(value)

R 包:tidyr

data <- tidyr::pivot_longer(data,c(x1,x2),names_to='measure',values_to='value')

转换单个前缀时删除缺失测量行

Stata

greshape long x, by(id) keys(wave) dropmiss

R 包:tidyr

data <- tidyr::pivot_longer(data,c(x1,x2),names_to='wave',names_prefix='x',names_transform=list(wave=as.integer),values_to='x',values_drop_na=TRUE)

与 Stata 有差异 固定单前缀流程;多前缀仅在所有转换值均缺失时删除该行。

使用 greshape 将文本键值展开为列

Stata

greshape spread value, keys(measure)

R 包:tidyr

data <- tidyr::pivot_wider(data,names_from=measure,values_from=value)

gsort

降序排列并将 Stata 缺失置前

Stata

gsort -x

R 包:base

data <- data[order(-data$x,na.last=FALSE), , drop=FALSE]

Stata 数值降序时缺失排在最前;因此显式设 na.last=FALSE。

另有 1 个示例及替代实现

组别升序且数值降序排序

Stata

gsort g -y

R 包:dplyr

data <- dplyr::arrange(data, g, dplyr::desc(y))

gstats

在每组内分别压缩极端值

Stata

gstats winsor x, by(g) cuts(25 75) replace

R 包:dplyr

data <- dplyr::mutate(data,x={b <- stats::quantile(x,c(.25,.75),na.rm=TRUE,type=2); pmax(b[1],pmin(b[2],x))},.by=g)

与 Stata 有差异 各组使用独立的非加权 R type-2 阈值;全缺失组需显式规定处理方式。

按显式经验四分位数压缩两端极值

Stata

gstats winsor x, cuts(25 75) generate(z)

R 包:base

bounds <- stats::quantile(data$x,c(.25,.75),na.rm=TRUE,type=2); data$z <- pmax(bounds[1],pmin(bounds[2],data$x))

与 Stata 有差异 非加权流程,显式使用 R type-2 经验百分位规则;不声称已完成跨软件数值认证。

将经验四分位区间外的值设为缺失

Stata

gstats winsor x, cuts(25 75) trim generate(z)

R 包:base

bounds <- stats::quantile(data$x,c(.25,.75),na.rm=TRUE,type=2); data$z <- data$x; data$z[!is.na(data$x) & (data$x<bounds[1] | data$x>bounds[2])] <- NA_real_

与 Stata 有差异 截尾将尾部设为缺失并保留行;百分位规则为 R type 2,不声称加权结果一致。

gtoplevelsof

找出频数最高的两个完整类别

Stata

gtoplevelsof g, ntop(2)

R 包:dplyr

counts <- dplyr::count(data,g,name='n'); counts <- counts[order(-counts$n,counts$g),]; top <- utils::head(counts,2)

与 Stata 有差异 仅返回首位类别与计数;不生成 Stata 累计或 Other 行。gtop 为别名,不另计命令。

gunique

统计完整行键组合的唯一数

Stata

gunique g h

R 包:base

nrow(unique(data[c('g','h')]))

与 Stata 有差异 本例键完整;与不带 joint 的 gdistinct 不同,gunique 将全部所列列联合处理。

添加各组内不同值数

Stata

gunique h, by(g) generate(nunique)

R 包:dplyr

data <- dplyr::mutate(data,nunique=dplyr::n_distinct(h),.by=g)

与 Stata 有差异 本例分组列与数值列完整;不声称缺失类别处理方式一致。

hashsort

按组升序与数值降序稳定排序

Stata

hashsort g -x

R 包:base

data <- data[order(data$g,-data$x,method='radix'),,drop=FALSE]

与 Stata 有差异 仅使用完整数值键;R 基数排序对同键保持原顺序。不作速度比较声明。

insobs

在指定位置后插入缺失行

Stata

insobs 1, after(2)

R 包:base

data <- rbind(data[seq_len(2),,drop=FALSE],data[NA_integer_,,drop=FALSE],data[-seq_len(2),,drop=FALSE])

固定流程示例;更改时需同时调整对象名与列名。

在指定位置前插入缺失行

Stata

insobs 1, before(3)

R 包:base

data <- rbind(data[1:2,,drop=FALSE],data[NA_integer_,,drop=FALSE],data[3:6,,drop=FALSE])

固定流程示例;更改时需同时调整对象名与列名。

追加两行全部缺失的观测

Stata

insobs 2

R 包:base

data <- rbind(data,data[rep(NA_integer_,2),,drop=FALSE])

固定流程示例;更改时需同时调整对象名与列名。

inspect

统计负值、零、正值与缺失值

Stata

inspect x

R 包:base

c(negative=sum(data$x<0,na.rm=TRUE),zero=sum(data$x==0,na.rm=TRUE),positive=sum(data$x>0,na.rm=TRUE),missing=sum(is.na(data$x)))

与 Stata 有差异 仅给出符号与缺失计数;不含 Stata 直方图与整数诊断。

ipolate

保留插值范围之外的边界缺失

Stata

ipolate y x, generate(z)

R 包:base

data$z <- stats::approx(data$x,data$y,xout=data$x,rule=1)$y

isid

验证复合键唯一识别各行

Stata

isid g h

R 包:base

stopifnot(!anyNA(data[c('g','h')]),!anyDuplicated(data[c('g','h')]))
另有 2 个示例及替代实现

验证键唯一且无缺失

Stata

isid id

R 包:base

stopifnot(!anyNA(data$id),!anyDuplicated(data$id))

唯一键中允许一个普通缺失值

Stata

isid id, missok

R 包:base

stopifnot(!anyDuplicated(data$id))

joinby

在各组内形成全部匹配对

Stata

joinby g using other.dta

R 包:dplyr

data <- dplyr::inner_join(data,other,by='g',relationship='many-to-many')
另有 1 个示例及替代实现

组内配对时保留未匹配主表行

Stata

joinby g using other.dta, unmatched(master)

R 包:dplyr

data <- dplyr::left_join(data,other,by='g',relationship='many-to-many')

与 Stata 有差异 返回配对行,不附带 Stata _merge 指示变量。

keep

按指定顺序保留列

Stata

keep id x

R 包:base

data <- data[c('id','x')]
另有 7 个示例及替代实现

保留指定列均完整的行

Stata

keep if !missing(x, y)

R 包:base

data <- data[stats::complete.cases(data[c('x','y')]), , drop=FALSE]

用 dplyr 筛选一个类别

Stata

keep if g == 2

R 包:dplyr

data <- dplyr::filter(data, g == 2)

保留指定类别集合

Stata

keep if inlist(g, 1, 3)

R 包:base

data <- data[data$g %in% c(1,3), , drop=FALSE]

保留指定变量缺失的行

Stata

keep if missing(x)

R 包:base

data <- data[is.na(data$x), , drop=FALSE]

保留非空字符串

Stata

keep if s != ""

R 包:base

data <- data[!is.na(data$s) & data$s != '', , drop=FALSE]

与 Stata 有差异 Stata 字符串缺失是空文本;此处同时排除空文本与 R 的 NA。

保留超过阈值的非缺失观测

Stata

keep if x > 2 & x < .

R 包:base

data <- data[!is.na(data$x) & data$x > 2, , drop=FALSE]

按位置保留连续若干行

Stata

keep in 2/4

R 包:base

data <- data[2:4, , drop=FALSE]

固定流程示例;更改时需同时调整对象名与列名。

levelsof

保存不同的非缺失数值类别

Stata

levelsof g, local(groups)

R 包:base

groups <- sort(unique(data$g[!is.na(data$g)]))
另有 1 个示例及替代实现

列出含普通缺失的不同值

Stata

levelsof x, missing

R 包:base

sort(unique(data$x),na.last=TRUE)

list

查看指定行与列

Stata

list id x if g == 2

R 包:base

data[data$g==2,c('id','x'),drop=FALSE]
另有 2 个示例及替代实现

查看前几行的指定列

Stata

list id x in 1/3

R 包:utils

utils::head(data[c('id','x')],3)

查看最后几行

Stata

list in -2/l

R 包:utils

utils::tail(data,2)

固定流程示例;更改时需同时调整对象名与列名。

lookfor

不区分大小写搜索列名

Stata

lookfor income

R 包:base

names(data)[grepl('income',names(data),ignore.case=TRUE)]

与 Stata 有差异 仅搜索列名;要同时搜索变量标签,需加入各列 label 属性。

memory

测量一个 R 数据表占用的内存

Stata

memory

R 包:utils

utils::object.size(data)

报告单个对象的估计内存,而非 Stata 进程整体分配报告。

merge

记录仅主表、仅附表与匹配状态

Stata

merge 1:1 id using other.dta, generate(status)

R 包:dplyr

data$.master <- TRUE; other$.using <- TRUE; data <- dplyr::full_join(data,other,by='id',relationship='one-to-one'); data$status <- ifelse(is.na(data$.master),2L,ifelse(is.na(data$.using),1L,3L)); data$.master <- NULL; data$.using <- NULL

除非明确展示 update,非键列名需互不重复。dplyr 会为重名列添加后缀;普通 Stata merge 在匹配行保留主表取值,包括主表缺失值。

另有 7 个示例及替代实现

一对一合并中保留全部主表行

Stata

merge 1:1 id using other.dta, keep(master match) nogenerate

R 包:dplyr

data <- dplyr::left_join(data,other,by='id',relationship='one-to-one')

除非明确展示 update,非键列名需互不重复。dplyr 会为重名列添加后缀;普通 Stata merge 在匹配行保留主表取值,包括主表缺失值。

一对一合并中仅保留匹配键

Stata

merge 1:1 id using other.dta, keep(match) nogenerate

R 包:dplyr

data <- dplyr::inner_join(data,other,by='id',relationship='one-to-one')

除非明确展示 update,非键列名需互不重复。dplyr 会为重名列添加后缀;普通 Stata merge 在匹配行保留主表取值,包括主表缺失值。

合并时限定附表列

Stata

merge 1:1 id using other.dta, keepusing(y) nogenerate

R 包:dplyr

data <- dplyr::full_join(data,other[c('id','y')],by='id',relationship='one-to-one')

除非明确展示 update,非键列名需互不重复。dplyr 会为重名列添加后缀;普通 Stata merge 在匹配行保留主表取值,包括主表缺失值。

执行已验证的一对一完整合并

Stata

merge 1:1 id using other.dta, nogenerate

R 包:dplyr

stopifnot(!anyDuplicated(data$id),!anyDuplicated(other$id)); data <- dplyr::full_join(data,other,by='id',relationship='one-to-one')

除非明确展示 update,非键列名需互不重复。dplyr 会为重名列添加后缀;普通 Stata merge 在匹配行保留主表取值,包括主表缺失值。

用匹配附表值填补主表缺失

Stata

merge 1:1 id using other.dta, update nogenerate

R 包:dplyr

data <- dplyr::full_join(data,other,by='id',suffix=c('','.using'),relationship='one-to-one'); data$x <- dplyr::coalesce(data$x,data$x.using); data$x.using <- NULL

与 Stata 有差异 仅展示更新取值;不生成 Stata update 冲突状态码 4/5。 除非明确展示 update,非键列名需互不重复。dplyr 会为重名列添加后缀;普通 Stata merge 在匹配行保留主表取值,包括主表缺失值。

将唯一主表键扩展到多个匹配行

Stata

merge 1:m id using other.dta, nogenerate

R 包:dplyr

data <- dplyr::full_join(data,other,by='id',relationship='one-to-many')

除非明确展示 update,非键列名需互不重复。dplyr 会为重名列添加后缀;普通 Stata merge 在匹配行保留主表取值,包括主表缺失值。

将唯一组属性附加到多行观测

Stata

merge m:1 g using groups.dta, keep(master match) nogenerate

R 包:dplyr

data <- dplyr::left_join(data,groups,by='g',relationship='many-to-one')

除非明确展示 update,非键列名需互不重复。dplyr 会为重名列添加后缀;普通 Stata merge 在匹配行保留主表取值,包括主表缺失值。

missings

删除所选数值变量全部缺失的行

Stata

missings dropobs x y, force

R 包:base

data <- data[rowSums(!is.na(data[c('x','y')]))>0,,drop=FALSE]

删除完全缺失的数值列

Stata

missings dropvars, force

R 包:base

data <- data[!vapply(data,function(z) all(is.na(z)),logical(1))]

与 Stata 有差异 本例仅含数值。Stata 字符串缺失为空文本,在 R 中还需额外检验空串。

按数值变量报告缺失值数

Stata

missings report x y

R 包:base

colSums(is.na(data[c('x','y')]))

与 Stata 有差异 仅处理数值列。R 结果包括零计数;Stata 默认仅显示至少一次缺失的计数。

逐行统计数值缺失值数

Stata

missings tag x y, generate(nmiss)

R 包:base

data$nmiss <- rowSums(is.na(data[c('x','y')]))

misstable

统计联合缺失模式频数

Stata

misstable patterns x y

R 包:base

table(apply(is.na(data[c('x','y')]),1,paste0,collapse=''))

与 Stata 有差异 R 模式串中 TRUE 表示缺失;Stata 显示符号与排序不同。

另有 1 个示例及替代实现

统计各所选列缺失值数

Stata

misstable summarize x y

R 包:base

colSums(is.na(data[c('x','y')]))

mvdecode

将多个特殊编码转换为缺失

Stata

mvdecode x, mv(-99 -98)

R 包:base

data$x[data$x %in% c(-99,-98)] <- NA_real_
另有 1 个示例及替代实现

将特殊编码转换为带标记缺失

Stata

mvdecode x, mv(-99=.a)

R 包:haven

data$x[data$x %in% -99] <- haven::tagged_na('a')

与 Stata 有差异 带标记缺失保留标记,但 R 比较仍遵循 NA 语义。

mvencode

将缺失值编码为特殊数值

Stata

mvencode x, mv(-99)

R 包:base

data$x[is.na(data$x)] <- -99
另有 1 个示例及替代实现

只编码一种带标记缺失

Stata

mvencode x, mv(.a=-99)

R 包:haven

data$x[haven::is_tagged_na(data$x,'a')] <- -99

order

按字母顺序排列列

Stata

order _all, alphabetic

R 包:base

data <- data[sort(names(data))]

固定流程示例;更改时需同时调整对象名与列名。

另有 3 个示例及替代实现

将一列移到最后

Stata

order id, last

R 包:dplyr

data <- dplyr::relocate(data, id, .after=dplyr::last_col())

将一列移到另一列之后

Stata

order s, after(id)

R 包:dplyr

data <- dplyr::relocate(data, s, .after=id)

将指定列移到最前

Stata

order y id, first

R 包:base

data <- data[c('y','id',setdiff(names(data),c('y','id')))]

putmata

将数值列复制为 R 矩阵

Stata

putmata X=(x y)

R 包:base

X <- as.matrix(data[c('x','y')])

使用 R 矩阵代替独立 Mata 工作区;矩阵名 X 在本例固定。

将完整数值行复制为矩阵

Stata

putmata X=(x y), omitmissing

R 包:base

X <- as.matrix(data[stats::complete.cases(data[c('x','y')]),c('x','y')])

使用 R 矩阵代替 Mata;按所选列联合删除不完整行。

range

创建包含端点的等距网格

Stata

range z 0 1 5

R 包:base

data <- data.frame(z=seq(0,1,length.out=5))

按当前行数添加等距网格

Stata

range z 0 10

R 包:base

data$z <- seq(0,10,length.out=nrow(data))

创建递减数值网格

Stata

range z 10 0 6

R 包:base

data <- data.frame(z=seq(10,0,length.out=6))

rangestat

在各闭区间数值键邻域内计算均值

Stata

rangestat (mean) z=x, interval(key -1 1)

R 包:base

data$z <- vapply(data$key,function(k) mean(data$x[data$key>=k-1 & data$key<=k+1]),numeric(1))

与 Stata 有差异 小型完整数据流程,采用含端点的键偏移并纳入自身;平方复杂度扫描不适合大型数据。

从数值区间均值中排除当前行

Stata

rangestat (mean) z=x, interval(key -1 1) excludeself

R 包:base

data$z <- vapply(seq_len(nrow(data)),function(i) mean(data$x[seq_len(nrow(data))!=i & data$key>=data$key[i]-1 & data$key<=data$key[i]+1]),numeric(1))

与 Stata 有差异 排除当前行本身而不是所有相同键;本例每个邻域还有其他观测,空邻域需另设 NA 处理。

在各闭区间数值键邻域内计算总和

Stata

rangestat (sum) z=x, interval(key -1 1)

R 包:base

data$z <- vapply(data$key,function(k) sum(data$x[data$key>=k-1 & data$key<=k+1]),numeric(1))

与 Stata 有差异 本例仅含完整有限键与数值;缺失边界、分组与权重需显式扩展。

recast

将整数列转换为双精度

Stata

recast double x

R 包:base

data$x <- as.double(data$x)
另有 1 个示例及替代实现

将整值存为 R 整数

Stata

recast long x

R 包:base

data$x <- as.integer(data$x)

与 Stata 有差异 仅用于 R 整数范围内的整值;Stata 存储范围不同。

recode

将整数类别合并为两组

Stata

recode x (1/2=0) (3/6=1), generate(binary)

R 包:base

data$binary <- ifelse(is.na(data$x),NA_real_,ifelse(data$x<=2,0,1))

与 Stata 有差异 示例值为 1 至 6 的整数;范围外取值需另设分支。

另有 1 个示例及替代实现

重编码指定值并保留其他值

Stata

recode x (1=10) (2=20), generate(z)

R 包:base

data$z <- data$x; data$z[data$x %in% 1] <- 10; data$z[data$x %in% 2] <- 20

rename

同时重命名多列

Stata

rename (x y) (income hours)

R 包:base

names(data)[match(c('x','y'),names(data))] <- c('income','hours')
另有 4 个示例及替代实现

将全部列名转为小写

Stata

rename *, lower

R 包:base

names(data) <- tolower(names(data))

固定流程示例;更改时需同时调整对象名与列名。

将全部列名转为大写

Stata

rename *, upper

R 包:base

names(data) <- toupper(names(data))

固定流程示例;更改时需同时调整对象名与列名。

替换列名前缀

Stata

rename old* new*

R 包:base

names(data) <- sub('^old','new',names(data))

固定流程示例;更改时需同时调整对象名与列名。

用 dplyr 重命名一列

Stata

rename x income

R 包:dplyr

data <- dplyr::rename(data, income=x)

replace

替换空文本而保留 NA

Stata

replace s = "unknown" if s == ""

R 包:base

data$s[!is.na(data$s) & data$s==''] <- 'unknown'

与 Stata 有差异 R 区分空文本与 NA;本例仅替换空文本。

另有 4 个示例及替代实现

将特定编码改为缺失

Stata

replace x = . if x == 2

R 包:base

data$x[data$x %in% 2] <- NA_real_

将数值缺失替换为零

Stata

replace x = 0 if missing(x)

R 包:base

data$x[is.na(data$x)] <- 0

仅修改指定类别中的值

Stata

replace x = x * 100 if g == 1

R 包:base

data$x[data$g %in% 1] <- data$x[data$g %in% 1] * 100

使用另一列填补缺失值

Stata

replace x = y if missing(x)

R 包:base

data$x[is.na(data$x)] <- data$y[is.na(data$x)]

reshape

同时转换多个平行测量前缀

Stata

reshape long x y, i(id) j(wave)

R 包:tidyr

data <- tidyr::pivot_longer(data,cols=c(x1,x2,y1,y2),names_to=c('.value','wave'),names_pattern='([xy])([12])',names_transform=list(wave=as.integer))

固定双前缀示例;所有命名模式与源列名需同步更改。

另有 3 个示例及替代实现

将宽格式测量前缀转换为长格式行

Stata

reshape long x, i(id) j(wave)

R 包:tidyr

data <- tidyr::pivot_longer(data,cols=c(x1,x2),names_to='wave',names_prefix='x',names_transform=list(wave=as.integer),values_to='x')

固定 x1/x2 前缀示例;源列名、前缀与输出名需同步调整。

转宽格式时使用文本后缀

Stata

reshape wide x, i(id) j(group) string

R 包:tidyr

data <- tidyr::pivot_wider(data,id_cols=id,names_from=group,values_from=x,names_prefix='x')

与 Stata 有差异 固定字符串后缀流程;组合键必须唯一。

将唯一长格式测量转换为宽格式列

Stata

reshape wide x, i(id) j(wave)

R 包:tidyr

data <- tidyr::pivot_wider(data,id_cols=id,names_from=wave,values_from=x,names_prefix='x')

与 Stata 有差异 要求 id-wave 对唯一;重复值应显式处理,不能静默汇总。

separate

生成各组专属数值列

Stata

separate x, by(g)

R 包:base

for (k in sort(unique(data$g))) data[[paste0('x',k)]] <- ifelse(data$g==k,data$x,NA_real_)

按二元条件拆成专属列

Stata

separate y, by(g == 1) generate(z)

R 包:base

data$z0 <- ifelse(data$g!=1,data$y,NA_real_); data$z1 <- ifelse(data$g==1,data$y,NA_real_)

生成列前缀 z 在本例固定;z0 与 z1 分别对应假和真分支。

seqvar

短整数序列结束后将其余行保留为缺失

Stata

seqvar z = 1/3

R 包:base

data$z <- rep(NA_integer_,nrow(data)); data$z[seq_len(min(3L,nrow(data)))] <- seq_len(min(3L,nrow(data)))

创建带指定间隔的整数序列

Stata

seqvar z = 1/3 5/7

R 包:base

data$z <- c(1:3,5:7)

snapshot

恢复临时数据快照

Stata

snapshot restore 1

R 包:base

data <- readRDS(path)

恢复显式指定的 RDS 文件,而非 Stata 编号快照。

将数据快照临时保存到磁盘

Stata

snapshot save

R 包:base

path <- tempfile(fileext='.rds'); saveRDS(data,path)

使用 RDS 文件路径,代替 Stata 带编号的交互快照管理器。

sort

依次按两列升序排列

Stata

sort g x

R 包:base

data <- data[order(data$g,data$x,na.last=TRUE), , drop=FALSE]
另有 2 个示例及替代实现

同键值内保留原顺序

Stata

sort g, stable

R 包:base

data <- data[order(data$g,method='radix'), , drop=FALSE]

按数值排序并将缺失置后

Stata

sort x

R 包:base

data <- data[order(data$x, na.last=TRUE), , drop=FALSE]

splitsample

随机分配均衡的两半样本

Stata

splitsample, generate(sample)

R 包:base

data$sample <- sample(rep(1:2,length.out=nrow(data)))

与 Stata 有差异 R 与 Stata 随机分配不同;此例样本量为偶数。

随机分配三个等量子样本

Stata

splitsample, generate(sample) nsplit(3)

R 包:base

data$sample <- sample(rep(1:3,each=nrow(data)/3))

与 Stata 有差异 要求行数可被三整除;不同系统随机分配不同。

stack

成对纵向堆叠多列

Stata

stack x a y b, into(value amount) clear

R 包:base

data <- rbind(data.frame(value=data$x,amount=data$a,`_stack`=1L,check.names=FALSE),data.frame(value=data$y,amount=data$b,`_stack`=2L,check.names=FALSE))

将两列纵向堆叠并标记来源

Stata

stack x y, into(value) clear

R 包:base

data <- data.frame(value=c(data$x,data$y),`_stack`=rep(1:2,each=nrow(data)),check.names=FALSE)

tostring

为数值编号补前导零

Stata

tostring x, generate(s) format(%06.0f)

R 包:base

data$s <- sprintf('%06.0f',data$x)
另有 1 个示例及替代实现

将数字格式化为两位小数文本

Stata

tostring x, generate(s) format(%9.2f)

R 包:base

data$s <- sprintf('%.2f',data$x)

与 Stata 有差异 R 示例省略字段宽度填充;数值按显示精度舍入并保存为文本。

xi

生成省略最低类别的虚拟变量

Stata

xi i.g

R 包:tidystata

data <- dplyr::select(tidystata::as_dummy(data, g, .names = "index"), -tidyselect::any_of("g_1"))

与 Stata 有差异 保留原有列,并省略首个已观测类别。数值类别按取值排序;R 因子按水平顺序排列,须使其与 Stata 的省略类别一致。Stata 按类别代码命名虚拟变量,R 通过 .names=“index” 按已观测类别编号。建模时使用 factor(g);不复现 xi: 交互展开。

xpose

转置全数值数据表

Stata

xpose, clear

R 包:base

data <- as.data.frame(t(as.matrix(data)))

与 Stata 有差异 输入必须全为数值;R 输出列名不同于 Stata 的 v1、v2。

另有 1 个示例及替代实现

转置并保留原列名

Stata

xpose, clear varname

R 包:base

oldnames <- names(data); data <- as.data.frame(t(as.matrix(data))); data[['_varname']] <- oldnames

与 Stata 有差异 输入必须全为数值。原列名保存在 _varname;R 转置后列名可能不同。