Descriptive tables
Start with the expanded example for each command. Open the variants for options and alternative R approaches. Read the qualifications before adapting the code.
collapse
Replace rows with group nonmissing counts
Stata
collapse (count) z=x, by(g)R Package:dplyr
data <- dplyr::summarise(data,z=sum(!is.na(x)),.by=g)11 more examples and alternatives
Replace rows with group first values including missing
Stata
collapse (first) z=x, by(g)R Package:dplyr
data <- dplyr::summarise(data,z=dplyr::first(x),.by=g)Replace rows with group first nonmissing values
Stata
collapse (firstnm) z=x, by(g)R Package:dplyr
data <- dplyr::summarise(data,z=dplyr::first(x[!is.na(x)]),.by=g)Replace rows with group last values including missing
Stata
collapse (last) z=x, by(g)R Package:dplyr
data <- dplyr::summarise(data,z=dplyr::last(x),.by=g)Replace rows with group last nonmissing values
Stata
collapse (lastnm) z=x, by(g)R Package:dplyr
data <- dplyr::summarise(data,z=dplyr::last(x[!is.na(x)]),.by=g)Replace rows with group maxima
Stata
collapse (max) z=x, by(g)R Package:dplyr
data <- dplyr::summarise(data, z = if (all(is.na(x))) NA_real_ else max(x, na.rm = TRUE), .by = g)Collapse integer-frequency-weighted values to a mean
Stata
collapse (mean) x [fw=w]R Package:stats
data <- data.frame(x=stats::weighted.mean(data$x,data$w))Differs from Stata Frequency-weighted mean only; no inference or weighted-variance formula is implied.
Use common complete cases for group summaries
Stata
collapse (mean) x y, cw by(g)R Package:dplyr
data <- data[stats::complete.cases(data[c('x','y')]),]; data <- dplyr::summarise(data,dplyr::across(c(x,y),mean),.by=g)Replace rows with group means
Stata
collapse (mean) z=x, by(g)R Package:dplyr
data <- dplyr::summarise(data,z=mean(x,na.rm=TRUE),.by=g)Replace rows with group medians
Stata
collapse (median) z=x, by(g)R Package:dplyr
data <- dplyr::summarise(data,z=stats::median(x,na.rm=TRUE),.by=g)Replace rows with group minima
Stata
collapse (min) z=x, by(g)R Package:dplyr
data <- dplyr::summarise(data, z = if (all(is.na(x))) NA_real_ else min(x, na.rm = TRUE), .by = g)Replace rows with group totals
Stata
collapse (sum) z=x, by(g)R Package:dplyr
data <- dplyr::summarise(data,z=sum(x,na.rm=TRUE),.by=g)contract
Count observed combinations of two categories
Stata
contract g h, freq(n)R Package:dplyr
data <- dplyr::count(data,g,h,name='n')Include unobserved combinations with zero frequency
Stata
contract g h, freq(n) zeroR Package:base
data <- as.data.frame(table(data$g,data$h)); names(data) <- c('g','h','n')Replace observations with category frequencies
Stata
contract g, freq(n)R Package:dplyr
data <- dplyr::count(data,g,name='n')Create cumulative frequencies and percentages
Stata
contract g, freq(n) cfreq(cn) cpercent(cp)R Package:dplyr
data <- dplyr::count(data,g,name='n'); data$cn <- cumsum(data$n); data$cp <- 100*data$cn/sum(data$n)Create category frequencies and percentages
Stata
contract g, freq(n) percent(p)R Package:dplyr
data <- dplyr::count(data,g,name='n'); data$p <- 100*data$n/sum(data$n)2 more examples and alternatives
Create category counts from integer frequency weights
Stata
contract g [fw=w], freq(n)R Package:dplyr
data <- dplyr::summarise(data,n=sum(w),.by=g)Exclude missing categories before contracting
Stata
contract g, nomissR Package:dplyr
data <- dplyr::count(data[!is.na(data$g)&data$g!='',,drop=FALSE],g,name='_freq')Differs from Stata Excludes both empty strings and R NA to match Stata’s nonmissing string categories.
summarize
Get detailed empirical percentiles
Stata
summarize x, detailR Package:base
stats::quantile(data$x,c(.01,.05,.1,.25,.5,.75,.9,.95,.99),na.rm=TRUE,type=2)Differs from Stata Percentile portion of summarize detail, using R type 2; skewness/kurtosis are not returned here.
1 more examples and alternatives
Compute mean-only summary components
Stata
summarize x, meanonlyR Package:base
c(n=sum(!is.na(data$x)),mean=mean(data$x,na.rm=TRUE),min=min(data$x,na.rm=TRUE),max=max(data$x,na.rm=TRUE))tab1
Make separate one-way frequency tables
Stata
tab1 g hR Package:base
lapply(data[c('g','h')],table)tab2
Make each pairwise contingency table
Stata
tab2 g h kR Package:base
pairs <- utils::combn(c('g','h','k'),2,simplify=FALSE); lapply(pairs,function(p) table(data[[p[1]]],data[[p[2]]]))tabdisp
Display a complete table of precomputed cell values
Stata
tabdisp g h, cellvar(value)R Package:stats
stopifnot(!anyDuplicated(data[c('g','h')])); stats::xtabs(value~g+h,data=data,na.action=stats::na.pass)Differs from Stata Requires one row for every cell and unique keys; xtabs would otherwise sum duplicates or fill absent cells with zero.
tabstat
Compare count, mean and spread across numeric columns
Stata
tabstat x y, statistics(n mean sd) columns(statistics)R Package:base
sapply(data[c('x','y')],function(z) c(n=sum(!is.na(z)),mean=mean(z,na.rm=TRUE),sd=stats::sd(z,na.rm=TRUE)))14 more examples and alternatives
Summarize nonmissing counts and means by category
Stata
tabstat x, by(g) statistics(n mean)R Package:dplyr
data |> dplyr::group_by(g) |> dplyr::summarise(n=sum(!is.na(x)),mean=mean(x,na.rm=TRUE),.groups='drop')Return the interquartile range as a descriptive statistic
Stata
tabstat x, statistics(iqr)R Package:base
with(data,diff(stats::quantile(x,c(.25,.75),na.rm=TRUE,type=2)))Differs from Stata Uses the Stata-default empirical percentile rule through R quantile type 2.
Return the maximum as a descriptive statistic
Stata
tabstat x, statistics(max)R Package:base
with(data,max(x,na.rm=TRUE))Differs from Stata Unweighted descriptive statistic; no survey or sampling-design correction is applied.
Return the mean as a descriptive statistic
Stata
tabstat x, statistics(mean)R Package:base
with(data,mean(x,na.rm=TRUE))Differs from Stata Unweighted descriptive statistic; no survey or sampling-design correction is applied.
Return the minimum as a descriptive statistic
Stata
tabstat x, statistics(min)R Package:base
with(data,min(x,na.rm=TRUE))Differs from Stata Unweighted descriptive statistic; no survey or sampling-design correction is applied.
Return the nonmissing count as a descriptive statistic
Stata
tabstat x, statistics(n)R Package:base
with(data,sum(!is.na(x)))Differs from Stata Unweighted descriptive statistic; no survey or sampling-design correction is applied.
Return the 25th percentile as a descriptive statistic
Stata
tabstat x, statistics(p25)R Package:base
with(data,as.numeric(stats::quantile(x,.25,na.rm=TRUE,type=2)))Differs from Stata Uses the Stata-default empirical percentile rule through R quantile type 2.
Return the median as a descriptive statistic
Stata
tabstat x, statistics(p50)R Package:base
with(data,stats::median(x,na.rm=TRUE))Differs from Stata Unweighted descriptive statistic; no survey or sampling-design correction is applied.
Return the 75th percentile as a descriptive statistic
Stata
tabstat x, statistics(p75)R Package:base
with(data,as.numeric(stats::quantile(x,.75,na.rm=TRUE,type=2)))Differs from Stata Uses the Stata-default empirical percentile rule through R quantile type 2.
Return the range as a descriptive statistic
Stata
tabstat x, statistics(range)R Package:base
with(data,diff(range(x,na.rm=TRUE)))Differs from Stata Unweighted descriptive statistic; no survey or sampling-design correction is applied.
Return the sample standard deviation as a descriptive statistic
Stata
tabstat x, statistics(sd)R Package:base
with(data,stats::sd(x,na.rm=TRUE))Differs from Stata Unweighted descriptive statistic; no survey or sampling-design correction is applied.
Return the standard error of the mean as a descriptive statistic
Stata
tabstat x, statistics(semean)R Package:base
with(data,stats::sd(x,na.rm=TRUE)/sqrt(sum(!is.na(x))))Differs from Stata Unweighted descriptive statistic; no survey or sampling-design correction is applied.
Return the sum as a descriptive statistic
Stata
tabstat x, statistics(sum)R Package:base
with(data,sum(x,na.rm=TRUE))Differs from Stata Unweighted descriptive statistic; no survey or sampling-design correction is applied.
Return the sample variance as a descriptive statistic
Stata
tabstat x, statistics(variance)R Package:base
with(data,stats::var(x,na.rm=TRUE))Differs from Stata Unweighted descriptive statistic; no survey or sampling-design correction is applied.
tabulate
Count a single categorical variable
Stata
tabulate gR Package:base
table(data$g)7 more examples and alternatives
Tabulate integer frequency weights
Stata
tabulate g [fw=w]R Package:stats
stats::xtabs(w~g,data=data,na.action=stats::na.pass)Count a two-way contingency table
Stata
tabulate g hR Package:base
table(data$g,data$h)Compute percentages of all table cells
Stata
tabulate g h, cellR Package:base
100*prop.table(table(data$g,data$h))Compute percentages within each table column
Stata
tabulate g h, columnR Package:base
100*prop.table(table(data$g,data$h),margin=2)Compute percentages within each table row
Stata
tabulate g h, rowR Package:base
100*prop.table(table(data$g,data$h),margin=1)Create a full set of category indicators
Stata
tabulate g, generate(d)R Package:tidystata
indicators <- tidystata::as_dummy(dplyr::select(data, g), g, .remove = TRUE)Differs from Stata Keeps all observations; a missing category gives NA in every dummy. R returns a separate data frame with category-based names; the Stata stub d is not a templated output name.
Include missing categories in a frequency table
Stata
tabulate g, missingR Package:base
table(data$g,useNA='ifany')Differs from Stata Maps R NA to an explicit table category; empty character strings remain a separate R value.