数据管理
先查看各命令展开的示例,再按需展开其他选项及 R 实现。改写代码前,请阅读适用条件及差异说明。
append
追加列集合不同的数据表
Stata
append using other.dtaR 包:dplyr
data <- dplyr::bind_rows(data,other)固定流程示例;更改时需同时调整对象名与列名。
另有 2 个示例及替代实现
仅追加附表所选列
Stata
append using other.dta, keep(x)R 包:dplyr
data <- dplyr::bind_rows(data,other['x'])assertnested
验证每个编号对应的组属性恒定
Stata
assertnested id, within(g)R 包:base
stopifnot(all(vapply(split(data$g,data$id),function(z) length(unique(z))==1L,logical(1))))cf
定位指定列取值不同的行
Stata
cf x using other.dta, verboseR 包:base
which(data$x != other$x | xor(is.na(data$x),is.na(other$x)))此流程仅检查 x;完整逐列报告需对各列进行比较。
验证两个数据表指定列的值一致
Stata
cf x y using other.dtaR 包:base
stopifnot(identical(unname(as.matrix(data[c('x','y')])),unname(as.matrix(other[c('x','y')]))))与 Stata 有差异 按行序比较已读入的 other 数据表;与 cf 一样忽略元数据。
clonevar
codebook
查看非缺失数、不同值数与范围
Stata
codebook x, compactR 包: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 yR 包: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 == 1R 包:base
with(subset(data,g==1),table(sign(x-y),useNA='ifany'))与 Stata 有差异 仅返回大小关系计数;差值幅度需另行汇总。
compress
count
统计指定列均完整的行数
Stata
count if !missing(x, y)R 包:base
sum(stats::complete.cases(data[c('x','y')]))cross
cumul
生成变量的经验累积分布
Stata
cumul x, generate(c)R 包:dplyr
data$c <- dplyr::row_number(data$x) / sum(!is.na(data$x))与 Stata 有差异 缺失值仍为缺失,且不计入分母。Stata 默认对相同取值按任意顺序赋予不同的累积值,R 按行顺序处理相同取值。权重及 by() 需另行按组或加权计算。
datasignature
验证数据匹配已保存的 R 签名
Stata
datasignature confirmR 包:base
stopifnot(identical(signature,serialize(data,NULL,version=2)))R 特有的字节比较;不兼容 Stata 的 .dtasig 文件。
describe
destring
另有 3 个示例及替代实现
解析以逗号为小数点的字段
Stata
destring s, generate(x) dpcommaR 包: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))drop
另有 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 <= 2R 包:dplyr
data <- dplyr::filter(data, is.na(x) | x > 2)与 Stata 有差异 Stata 数值缺失大于有限值;显式 is.na 分支保留这些行。
按位置删除连续行
Stata
drop in 2/4R 包:base
data <- data[-(2:4), , drop=FALSE]固定流程示例;更改时需同时调整对象名与列名。
ds
duplicates
每个重复键仅保留首条观测
Stata
duplicates drop id, forceR 包:base
data <- data[!duplicated(data$id),,drop=FALSE]另有 3 个示例及替代实现
查看重复键的全部组成员
Stata
duplicates list idR 包:base
data[duplicated(data$id)|duplicated(data$id,fromLast=TRUE),,drop=FALSE]汇总重复次数、观测数与重复盈余
Stata
duplicates report idR 包: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)))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 = 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 = 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), fieldR 包: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), missingR 包: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 = tag(g)R 包:base
data$z <- as.integer(!is.na(data$g) & !duplicated(data$g))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) mergeR 包:dplyr
data <- dplyr::mutate(data,z=mean(x,na.rm=TRUE),.by=g)fillin
补全缺失的类别键组合
Stata
fillin g hR 包:tidyr
data <- tidyr::complete(data,g,h)与 Stata 有差异 返回补全表但不带 Stata _fillin 标记;因子水平可能添加未使用的 R 类别。
flevelsof
fmerge
fralias
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 中需显式复制。
frlink
验证并创建一对一数据表链接
Stata
frlink 1:1 id, frame(lookup)R 包:base
stopifnot(!anyDuplicated(data$id),!anyDuplicated(lookup$id)); link <- match(data$id,lookup$id)link 是本例固定 R 对象名;未匹配键产生 NA。源表改变后需重建。
frunalias
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) mergeR 包: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')gdistinct
分别统计多列不同值数
Stata
gdistinct g hR 包:base
vapply(data[c('g','h')],function(z) length(unique(z[!is.na(z)])),integer(1))gduplicates
每个复合键仅保留首行
Stata
gduplicates drop g h, forceR 包:base
data <- data[!duplicated(data[c('g','h')]),,drop=FALSE]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))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 = _nR 包: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 = _NR 包:dplyr
data <- dplyr::mutate(data,n=dplyr::n(),.by=g)标记排序后各组的首个观测
Stata
bysort id (year): generate first = _n == 1R 包: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 prior = x[_n-1]R 包:dplyr
data$prior <- dplyr::lag(data$x)与 Stata 有差异 按行位置移动;不涉及时间间隔或 tsset 语义。
getmata
gisid
验证含普通缺失的复合键唯一性
Stata
gisid g h, missokR 包:base
stopifnot(!anyDuplicated(data[c('g','h')]))与 Stata 有差异 允许普通缺失作为键值;此处未表示 Stata 扩展缺失类别。
glevelsof
列出不同的完整多列键
Stata
glevelsof g hR 包:base
levels <- unique(data[c('g','h')]); levels <- levels[do.call(order,levels),,drop=FALSE]与 Stata 有差异 返回键表而非空格分隔局部宏;本例键均无缺失。
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) dropmissR 包: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 有差异 固定单前缀流程;多前缀仅在所有转换值均缺失时删除该行。
gsort
降序排列并将 Stata 缺失置前
Stata
gsort -xR 包:base
data <- data[order(-data$x,na.last=FALSE), , drop=FALSE]Stata 数值降序时缺失排在最前;因此显式设 na.last=FALSE。
gstats
在每组内分别压缩极端值
Stata
gstats winsor x, by(g) cuts(25 75) replaceR 包: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 hR 包: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 -xR 包: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])固定流程示例;更改时需同时调整对象名与列名。
inspect
统计负值、零、正值与缺失值
Stata
inspect xR 包: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
isid
验证复合键唯一识别各行
Stata
isid g hR 包:base
stopifnot(!anyNA(data[c('g','h')]),!anyDuplicated(data[c('g','h')]))joinby
在各组内形成全部匹配对
Stata
joinby g using other.dtaR 包: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
另有 7 个示例及替代实现
保留指定列均完整的行
Stata
keep if !missing(x, y)R 包:base
data <- data[stats::complete.cases(data[c('x','y')]), , drop=FALSE]保留指定类别集合
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]levelsof
保存不同的非缺失数值类别
Stata
levelsof g, local(groups)R 包:base
groups <- sort(unique(data$g[!is.na(data$g)]))list
lookfor
不区分大小写搜索列名
Stata
lookfor incomeR 包:base
names(data)[grepl('income',names(data),ignore.case=TRUE)]与 Stata 有差异 仅搜索列名;要同时搜索变量标签,需加入各列 label 属性。
memory
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) nogenerateR 包: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) nogenerateR 包: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) nogenerateR 包: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, nogenerateR 包: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 nogenerateR 包: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, nogenerateR 包:dplyr
data <- dplyr::full_join(data,other,by='id',relationship='one-to-many')除非明确展示 update,非键列名需互不重复。dplyr 会为重名列添加后缀;普通 Stata merge 在匹配行保留主表取值,包括主表缺失值。
missings
删除所选数值变量全部缺失的行
Stata
missings dropobs x y, forceR 包:base
data <- data[rowSums(!is.na(data[c('x','y')]))>0,,drop=FALSE]删除完全缺失的数值列
Stata
missings dropvars, forceR 包:base
data <- data[!vapply(data,function(z) all(is.na(z)),logical(1))]与 Stata 有差异 本例仅含数值。Stata 字符串缺失为空文本,在 R 中还需额外检验空串。
按数值变量报告缺失值数
Stata
missings report x yR 包:base
colSums(is.na(data[c('x','y')]))与 Stata 有差异 仅处理数值列。R 结果包括零计数;Stata 默认仅显示至少一次缺失的计数。
misstable
统计联合缺失模式频数
Stata
misstable patterns x yR 包:base
table(apply(is.na(data[c('x','y')]),1,paste0,collapse=''))与 Stata 有差异 R 模式串中 TRUE 表示缺失;Stata 显示符号与排序不同。
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
order
按字母顺序排列列
Stata
order _all, alphabeticR 包:base
data <- data[sort(names(data))]固定流程示例;更改时需同时调整对象名与列名。
另有 3 个示例及替代实现
将一列移到最后
Stata
order id, lastR 包:dplyr
data <- dplyr::relocate(data, id, .after=dplyr::last_col())将一列移到另一列之后
Stata
order s, after(id)R 包:dplyr
data <- dplyr::relocate(data, s, .after=id)putmata
将数值列复制为 R 矩阵
Stata
putmata X=(x y)R 包:base
X <- as.matrix(data[c('x','y')])使用 R 矩阵代替独立 Mata 工作区;矩阵名 X 在本例固定。
range
创建包含端点的等距网格
Stata
range z 0 1 5R 包:base
data <- data.frame(z=seq(0,1,length.out=5))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) excludeselfR 包: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
另有 1 个示例及替代实现
将整值存为 R 整数
Stata
recast long xR 包: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 的整数;范围外取值需另设分支。
rename
同时重命名多列
Stata
rename (x y) (income hours)R 包:base
names(data)[match(c('x','y'),names(data))] <- c('income','hours')另有 4 个示例及替代实现
将全部列名转为小写
Stata
rename *, lowerR 包:base
names(data) <- tolower(names(data))固定流程示例;更改时需同时调整对象名与列名。
将全部列名转为大写
Stata
rename *, upperR 包:base
names(data) <- toupper(names(data))固定流程示例;更改时需同时调整对象名与列名。
替换列名前缀
Stata
rename old* new*R 包:base
names(data) <- sub('^old','new',names(data))固定流程示例;更改时需同时调整对象名与列名。
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 = x * 100 if g == 1R 包:base
data$x[data$g %in% 1] <- data$x[data$g %in% 1] * 100reshape
同时转换多个平行测量前缀
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) stringR 包: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_)seqvar
短整数序列结束后将其余行保留为缺失
Stata
seqvar z = 1/3R 包:base
data$z <- rep(NA_integer_,nrow(data)); data$z[seq_len(min(3L,nrow(data)))] <- seq_len(min(3L,nrow(data)))snapshot
恢复临时数据快照
Stata
snapshot restore 1R 包:base
data <- readRDS(path)恢复显式指定的 RDS 文件,而非 Stata 编号快照。
sort
依次按两列升序排列
Stata
sort g xR 包:base
data <- data[order(data$g,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) clearR 包: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))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.gR 包: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, clearR 包:base
data <- as.data.frame(t(as.matrix(data)))与 Stata 有差异 输入必须全为数值;R 输出列名不同于 Stata 的 v1、v2。
另有 1 个示例及替代实现
转置并保留原列名
Stata
xpose, clear varnameR 包:base
oldnames <- names(data); data <- as.data.frame(t(as.matrix(data))); data[['_varname']] <- oldnames与 Stata 有差异 输入必须全为数值。原列名保存在 _varname;R 转置后列名可能不同。