Xử lý dữ liệu

Minh họa tạo bảng tổng hợp kết quả kiểm định thống kê

Sử dụng lệnh table với tùy chọn command trên Stata 17

Về cơ bản, chúng ta có thể sử dụng lệnh table với một số tuỳ chọn cơ bản như nototals, totals(), statistic(), nformat(), sformat(), và style() để tạo các bảng thống kê đơn giản. Bài viết này tôi sẽ giới thiệu cách sử dụng tùy chọn command của câu lệnh table để tạo các bảng tổng hợp các kết quả kiểm định thống kê trong thống kê mô tả.

Dữ liệu

Chúng ta tiếp tục thực hành trên bộ dữ liệu NHANES-II 1

. webuse nhanes2, clear

. describe highbp age hgb hct iron albumin vitaminc zinc copper lead     ///
>     height weight bmi bpsystol bpdiast tcresult tgresult hdresult

Variable      Storage   Display    Value
    name         type    format    label      Variable label
───────────────────────────────────────────────────────────────────────────────────────────────────────────────
highbp          byte    %8.0g               * High blood pressure
age             byte    %9.0g                 Age (years)
hgb             float   %9.0g                 Hemoglobin (g/dL)
hct             float   %9.0g                 Hematocrit (%)
iron            int     %9.0g                 Serum iron (mcg/dL)
albumin         float   %9.0g                 Serum albumin (g/dL)
vitaminc        float   %9.0g                 Serum vitamin C (mg/dL)
zinc            int     %9.0g                 Serum zinc (mcg/dL)
copper          int     %9.0g                 Serum copper (mcg/dL)
lead            byte    %9.0g                 Lead (mcg/dL)
height          float   %9.0g                 Height (cm)
weight          float   %9.0g                 Weight (kg)
bmi             float   %9.0g                 Body mass index (BMI)
bpsystol        int     %9.0g                 Systolic blood pressure
bpdiast         int     %9.0g                 Diastolic blood pressure
tcresult        int     %9.0g                 Serum cholesterol (mg/dL)
tgresult        int     %9.0g                 Serum triglycerides (mg/dL)
hdresult        int     %9.0g                 High density lipids (mg/dL)

Bộ dữ liệu có một chỉ số huyết áp cao (highbp), tuổi (age) và các biến đo lường thực nghiệm khác. Bây giờ, tôi muốn kiểm tra xem có sự khác nhau về tình trạng huyết áp cao theo độ tuổi và các thông số khác. Sử dụng kiểm định t, lệnh ttest, tôi thực hiện như sau:

. ttest age, by(highbp)
Two-sample t test with equal variances
─────────┬────────────────────────────────────────────────────────────────────
   Group │     Obs        Mean    Std. err.   Std. dev.   [95% conf. interval]
─────────┼────────────────────────────────────────────────────────────────────
       0 │   5,975    42.16502    .2169725    16.77157    41.73968    42.59037
       1 │   4,376    54.97281    .2253767    14.90897    54.53095    55.41466
─────────┼────────────────────────────────────────────────────────────────────
Combined │  10,351    47.57965    .1692044    17.21483    47.24798    47.91133
─────────┼────────────────────────────────────────────────────────────────────
    diff │           -12.80779    .3185604               -13.43223   -12.18335
─────────┴────────────────────────────────────────────────────────────────────
    diff = mean(0) - mean(1)                                      t = -40.2052
H0: diff = 0                                     Degrees of freedom =    10349

    Ha: diff < 0                 Ha: diff != 0                 Ha: diff > 0
 Pr(T < t) = 0.0000         Pr(|T| > |t|) = 0.0000          Pr(T > t) = 1.0000

Có nhiều trị thống kê được hiển thị ở kết quả này như các giá trị p của t-test. Tuy nhiên, nhiều trị thống kê khác chưa được hiển thị ở bảng kết quả trên. Chúng ta có thể xem tất cả các giá trị trả về của câu lệnh bằng lệnh return list bên dưới.

. return list
scalars:
              r(level) =  95
                 r(sd) =  17.21482923023818
               r(sd_2) =  14.9089715191102
               r(sd_1) =  16.77156676799842
                 r(se) =  .3185603831285
                r(p_u) =  1
                r(p_l) =  0
                  r(p) =  0
                  r(t) =  -40.20520433030012
               r(df_t) =  10349
               r(mu_2) =  54.97280621572212
                r(N_2) =  4376
               r(mu_1) =  42.16502092050209
                r(N_1) =  5975

Từ các trị thống kê được tính toán ở trên, bây giờ tôi sẽ sử dụng tùy chọn commnand của câu lệnh table để chạy lại lệnh ttest ở trên và trích những giá trị thống kê quan tâm như tuổi trung bình của hai nhóm, huyết áp bình thường r(mu_1) và huyết áp cao r(mu_2).

Ở đây, tôi tạo thêm hai dimension là NormotensiveHypertensive ghi nhận tuổi trung bình của hai nhóm tương ứng. Tôi cũng tạo thêm một dimension Diff để ghi nhận sự chênh lệch tuổi trung bình giữa hai nhóm và dimension pvalue để hiển thị giá trị p-value được lưu trữ ở r(p).

. #delimit ;
delimiter now ;
.  table (command) (result),                  
>    command(Normotensive = r(mu_1)
>            Hypertensive = r(mu_2) 
>            Diff         = (r(mu_2) - r(mu_1))
>            pvalue       =  r(p)
>            : ttest age, by(highbp));

──────────────────────┬─────────────────────────────────────────────────
                      │  Normotensive   Hypertensive       Diff   pvalue
──────────────────────┼─────────────────────────────────────────────────
ttest age, by(highbp) │      42.16502       54.97281   12.80779        0
──────────────────────┴─────────────────────────────────────────────────

. #delimit cr
delimiter now cr

Bây giờ, tôi muốn thay thế dòng lệnh ttest age, by(highbp) ở cột đầu tiên của bảng bằng nhãn là Age (years). Để thực hiện điều này, đầu tiên tôi muốn liệt kê xem các giá trị nhãn của dimension command được tạo ra từ collection mặc định của lệnh table.

. collect label list command, all
  Collection: Table
   Dimension: command
       Label: Command option index
Level labels:
           1  ttest age, by(highbp)

Kết quả cho thấy dimension command có một level là 1 được gán nhãn là ttest age, by(highbp). Bây giờ, tôi đổi tên nhãn này bằng Age (years) qua lệnh collect label levels

. collect label levels command 1 "Age (years)", modify
. collect preview
────────────┬─────────────────────────────────────────────────
            │  Normotensive   Hypertensive       Diff   pvalue
────────────┼─────────────────────────────────────────────────
Age (years) │      42.16502       54.97281   12.80779        0
────────────┴─────────────────────────────────────────────────

Tiếp tục, tôi định dạng hiển thị một chữ số thập phân ở các cột Normotensive, Hypertensive, Diff và 4 số thập phân ở cột pvalue qua lệnh collect style cell, đồng thời loại bỏ đường kẻ đứng ở cột đầu tiên.

. collect style cell result[Normotensive Hypertensive Diff], nformat(%6.1f)
. collect style cell result[pvalue], nformat(%6.4f)
. collect style cell border_block, border(right, pattern(nil))
. collect preview
────────────────────────────────────────────────────────
             Normotensive   Hypertensive   Diff   pvalue
────────────────────────────────────────────────────────
Age (years)          42.2           55.0   12.8   0.0000
────────────────────────────────────────────────────────

Tôi đã có một bảng kết quả nhìn cũng được, tuy nhiên chỉ có một kết quả kiểm định. Bây giờ, tôi muốn tạo một bảng lớn hơn cho nhiều tham số khác.

Tạo bảng kiểm định thống kê

Tôi sẽ lặp lại các thao tác trên với việc sử dụng tùy chọn command() nhiều lần, mỗi lần ứng với một tham số.

. #delimit ;
delimiter now ;
. table (command) (result),
>    command(Normotensive = r(mu_1) Hypertensive = r(mu_2)
>            Diff = (r(mu_2)-r(mu_1)) pvalue = r(p)
>            : ttest age, by(highbp))
>    command(Normotensive = r(mu_1) Hypertensive = r(mu_2)
>            Diff = (r(mu_2)-r(mu_1)) pvalue = r(p)       
>            : ttest tcresult, by(highbp))                
>    command(Normotensive = r(mu_1) Hypertensive = r(mu_2)
>            Diff = (r(mu_2)-r(mu_1)) pvalue = r(p)       
>            : ttest tgresult, by(highbp))                
>    command(Normotensive = r(mu_1) Hypertensive = r(mu_2)
>            Diff = (r(mu_2)-r(mu_1)) pvalue = r(p)       
>            : ttest hdresult, by(highbp))                
>    nformat(%6.2f  Normotensive Hypertensive Diff)       
>    nformat(%6.4f  pvalue);

───────────────────────────┬──────────────────────────────────────────────
                           │  Normotensive   Hypertensive    Diff   pvalue
───────────────────────────┼──────────────────────────────────────────────
ttest age, by(highbp)      │         42.17          54.97   12.81   0.0000
ttest tcresult, by(highbp) │        208.73         229.88   21.15   0.0000
ttest tgresult, by(highbp) │        129.23         166.04   36.81   0.0000
ttest hdresult, by(highbp) │         49.94          49.22   -0.73   0.0195
───────────────────────────┴──────────────────────────────────────────────

. #delimit cr
delimiter now cr

Tiếp đến là định dạng các ô như bước trên. Tuy nhiên, để không phải lặp lại các thao tác, tôi tạo và sử dụng các local macro để thực hiện như sau:

. local lcmacro "Normotensive = r(mu_1) Hypertensive = r(mu_2) Diff = (r(mu_2)-r(mu_1)) pvalue = r(p)"
. display "`lcmacro'"
Normotensive = r(mu_1) Hypertensive = r(mu_2) Diff = (r(mu_2)-r(mu_1)) pvalue = r(p)

và tôi sử dụng [lcmacro] vừa tạo này trong tùy chọn command() như sau:

. #delimit ;
delimiter now ;
. table (command) (result),    
>    command(`lcmacro' : ttest age,      by(highbp))
>    command(`lcmacro' : ttest tcresult, by(highbp))
>    command(`lcmacro' : ttest tgresult, by(highbp))
>    command(`lcmacro' : ttest hdresult, by(highbp))
>    nformat(%6.2f  Normotensive Hypertensive Diff)
>    nformat(%6.0f  pvalue);

───────────────────────────┬──────────────────────────────────────────────
                           │  Normotensive   Hypertensive    Diff   pvalue
───────────────────────────┼──────────────────────────────────────────────
ttest age, by(highbp)      │         42.17          54.97   12.81        0
ttest tcresult, by(highbp) │        208.73         229.88   21.15        0
ttest tgresult, by(highbp) │        129.23         166.04   36.81        0
ttest hdresult, by(highbp) │         49.94          49.22   -0.73        0
───────────────────────────┴──────────────────────────────────────────────

. #delimit cr
delimiter now cr

Tôi sẽ bổ sung tất cả các tham số vào kiểm định

. #delimit ;
delimiter now ;
. table (command) (result), 
>    command(`lcmacro' : ttest age,      by(highbp))
>    command(`lcmacro' : ttest hgb,      by(highbp))
>    command(`lcmacro' : ttest hct,      by(highbp))
>    command(`lcmacro' : ttest iron,     by(highbp))
>    command(`lcmacro' : ttest albumin,  by(highbp))
>    command(`lcmacro' : ttest vitaminc, by(highbp))
>    command(`lcmacro' : ttest zinc,     by(highbp))
>    command(`lcmacro' : ttest copper,   by(highbp))
>    command(`lcmacro' : ttest lead,     by(highbp))
>    command(`lcmacro' : ttest height,   by(highbp))
>    command(`lcmacro' : ttest weight,   by(highbp))
>    command(`lcmacro' : ttest bmi,      by(highbp))
>    command(`lcmacro' : ttest bpsystol, by(highbp))
>    command(`lcmacro' : ttest bpdiast,  by(highbp))
>    command(`lcmacro' : ttest tcresult, by(highbp))
>    command(`lcmacro' : ttest tgresult, by(highbp))
>    command(`lcmacro' : ttest hdresult, by(highbp));

───────────────────────────┬────────────────────────────────────────────────────
                           │  Normotensive   Hypertensive        Diff     pvalue
───────────────────────────┼────────────────────────────────────────────────────
ttest age, by(highbp)      │      42.16502       54.97281    12.80779          0
ttest height, by(highbp)   │      167.7243       167.5506   -.1736495   .3661002
ttest weight, by(highbp)   │      68.26626       76.85565    8.589386   9.1e-181
ttest bmi, by(highbp)      │      24.20231       27.36081    3.158506   4.5e-241
ttest bpsystol, by(highbp) │       116.485       150.5388    34.05383          0
ttest bpdiast, by(highbp)  │      74.17222       92.01394    17.84172          0
ttest tcresult, by(highbp) │      208.7272       229.8798     21.1526   4.3e-105
ttest tgresult, by(highbp) │      129.2284       166.0427     36.8143   7.01e-41
ttest hdresult, by(highbp) │      49.94449       49.21784   -.7266526   .0194611
ttest hgb, by(highbp)      │      14.14038       14.42436    .2839752   4.99e-25
ttest hct, by(highbp)      │      41.65235       42.44271    .7903588   2.16e-27
ttest iron, by(highbp)     │       101.842       96.17436   -5.667648   5.70e-17
ttest albumin, by(highbp)  │      4.680295       4.654088   -.0262068   .0000896
ttest vitaminc, by(highbp) │      1.048238       1.016469   -.0317686   .0070212
ttest zinc, by(highbp)     │      87.06462       85.74782   -1.316802   .0000162
ttest copper, by(highbp)   │      125.0756       126.3356    1.259952   .0673572
ttest lead, by(highbp)     │      13.87513       14.93369    1.058555   2.36e-09
───────────────────────────┴────────────────────────────────────────────────────

. #delimit cr
delimiter now cr

Tiếp đến là đổi tên các label của các level, sử dụng collect label levels

. #delimit ;
delimiter now ;
. collect label levels command 1  "Age (years)"                 
>                           10 "Height (cm)"                 
>                           11 "Weight (kg)"                 
>                           12 "Body Mass Index"             
>                           13 "Systolic Blood Pressure"     
>                           14 "Diastolic Blood Pressure"    
>                           15 "Serum cholesterol (mg/dL)"   
>                           16 "Serum triglycerides (mg/dL)" 
>                           17 "High density lipids (mg/dL)" 
>                           2  "Hemoglobin (g/dL)"           
>                           3  "Hematocrit (%)"              
>                           4  "Serum iron (mcg/dL)"         
>                           5  "Serum albumin (g/dL)"        
>                           6  "Serum vitamin C (mg/dL)"     
>                           7  "Serum zinc (mcg/dL)"         
>                           8  "Serum copper (mcg/dL)"       
>                           9 "Lead (mcg/dL)"                
>                           , modify;

. #delimit cr
delimiter now cr
. collect preview
────────────────────────────┬────────────────────────────────────────────────────
                            │  Normotensive   Hypertensive        Diff     pvalue
────────────────────────────┼────────────────────────────────────────────────────
Age (years)                 │      42.16502       54.97281    12.80779          0
Height (cm)                 │      167.7243       167.5506   -.1736495   .3661002
Weight (kg)                 │      68.26626       76.85565    8.589386   9.1e-181
Body Mass Index             │      24.20231       27.36081    3.158506   4.5e-241
Systolic Blood Pressure     │       116.485       150.5388    34.05383          0
Diastolic Blood Pressure    │      74.17222       92.01394    17.84172          0
Serum cholesterol (mg/dL)   │      208.7272       229.8798     21.1526   4.3e-105
Serum triglycerides (mg/dL) │      129.2284       166.0427     36.8143   7.01e-41
High density lipids (mg/dL) │      49.94449       49.21784   -.7266526   .0194611
Hemoglobin (g/dL)           │      14.14038       14.42436    .2839752   4.99e-25
Hematocrit (%)              │      41.65235       42.44271    .7903588   2.16e-27
Serum iron (mcg/dL)         │       101.842       96.17436   -5.667648   5.70e-17
Serum albumin (g/dL)        │      4.680295       4.654088   -.0262068   .0000896
Serum vitamin C (mg/dL)     │      1.048238       1.016469   -.0317686   .0070212
Serum zinc (mcg/dL)         │      87.06462       85.74782   -1.316802   .0000162
Serum copper (mcg/dL)       │      125.0756       126.3356    1.259952   .0673572
Lead (mcg/dL)               │      13.87513       14.93369    1.058555   2.36e-09
────────────────────────────┴────────────────────────────────────────────────────

Cuối cùng là định dạng các ô và loại bỏ đường kẻ đứng ở cột đầu tiên bằng lệnh collect style cell

. collect style cell result[Normotensive Hypertensive Diff], nformat(%8.2f)
. collect style cell result[pvalue], nformat(%6.4f)
. collect style cell border_block, border(right, pattern(nil))
. collect preview
─────────────────────────────────────────────────────────────────────────
                             Normotensive   Hypertensive    Diff   pvalue
─────────────────────────────────────────────────────────────────────────
Age (years)                         42.17          54.97   12.81   0.0000
Height (cm)                        167.72         167.55   -0.17   0.3661
Weight (kg)                         68.27          76.86    8.59   0.0000
Body Mass Index                     24.20          27.36    3.16   0.0000
Systolic Blood Pressure            116.49         150.54   34.05   0.0000
Diastolic Blood Pressure            74.17          92.01   17.84   0.0000
Serum cholesterol (mg/dL)          208.73         229.88   21.15   0.0000
Serum triglycerides (mg/dL)        129.23         166.04   36.81   0.0000
High density lipids (mg/dL)         49.94          49.22   -0.73   0.0195
Hemoglobin (g/dL)                   14.14          14.42    0.28   0.0000
Hematocrit (%)                      41.65          42.44    0.79   0.0000
Serum iron (mcg/dL)                101.84          96.17   -5.67   0.0000
Serum albumin (g/dL)                 4.68           4.65   -0.03   0.0001
Serum vitamin C (mg/dL)              1.05           1.02   -0.03   0.0070
Serum zinc (mcg/dL)                 87.06          85.75   -1.32   0.0000
Serum copper (mcg/dL)              125.08         126.34    1.26   0.0674
Lead (mcg/dL)                       13.88          14.93    1.06   0.0000
─────────────────────────────────────────────────────────────────────────

Xuất kết quả ra file Word

Khi đã hài lòng với dạng hiển thị của bảng, tôi có thể xuất kết quả ra file Word. Sử dụng lệnh putdocx để thêm tiêu đề, các đề mục và những nội dung mô tả cần thiết trước khi chèn bảng vừa tạo. Cuối cùng, tôi sử dụng lệnh putdocx collect để xuất bảng kết quả ra tài liệu.

. putdocx begin
. putdocx paragraph, style(Title)
. putdocx text ("Hypertension in the United States")
. putdocx paragraph, style(Heading1)
. putdocx text ("The National Health and Nutrition Examination Survey (NHANES)")
. putdocx paragraph
. putdocx text ("Hypertension is a major cause of morbidity and mortality in ")
. putdocx text ("the United States. This report will explore the predictors ")
. putdocx text ("of hypertension using the NHANES dataset.")
. collect style putdocx,  layout(autofitcontents) ///
>      title("Table 2: Comparison of demographic, anthropometric, and lab results by Hypertension Status")

. putdocx collect
(collection Table posted to putdocx)
. putdocx save Table4.docx, replace
successfully replaced "D:/GitHub/TNS/premium/Table4.docx"

Tổng kết

Bài viết này tôi đã minh họa cách sử dụng tùy chọn command để tổng hợp các kết quả kiểm định t. Các bước thực hiện là khá đơn giản.

  • Đầu tiên, chạy câu lệnh kiểm định ttest
  • Xem các trị thống kê tính toán qua lệnh return list
  • Tạo bảng với các row, column của dimension result
  • Đặt câu lệnh thực hiện ở phần tùy chọn command
  • Thực hiện các tinh chỉnh về hiển thị như định dạng số, định dạng ô, đường viền…

Bài viết kế tiếp, tôi sẽ minh họa cách sử dụng tùy chọn command để tạo bảng tổng hợp các kết quả hồi quy.

Bài viết được tổng hợp từ The Stata Blog 2

Tài liệu tham khảo


  1. McDowell A, Engel A, Massey JT, Maurer KPlan and operation of the Second National Health and Nutrition Examination Survey, 1976-1980Vital Health Stat 11981;(15):1-144PMID: 7344293.↩︎
  2. Customizable tables in Stata 17, part 4: Table of statistical tests tại: https://blog.stata.com/2021/08/24/customizable-tables-in-stata-17-part-4-table-of-statistical-tests/↩︎
Back to top button