This example uses the National Ambulatory Medical Care Survey (NAMCS)
2019 Public Use File (PUF) to replicate certain tables from the National
Ambulatory Medical Care Survey: 2019 National Summary Tables. NAMCS
is “an annual nationally representative sample survey of visits to
non-federal office-based patient care physicians, excluding
anesthesiologists, radiologists, and pathologists.” Note that the unit
of observation is visits, not patients – this distinction is important
since a single patient can make multiple visits.
Selected variables from NAMCS 2019 come with the
surveytable
package, for use in examples, in an object
called namcs2019sv
.
Begin
Begin by loading the surveytable
package.
Now, specify the survey that you’d like to analyze.
Survey info {NAMCS 2019 PUF}
|
Variables
|
Observations
|
Design
|
33
|
8,250
|
Stratified 1 - level Cluster Sampling design (with replacement) With
(398) clusters. namcs2019sv = survey::svydesign(ids = ~CPSUM, strata =
~CSTRATM, weights = ~PATWT , data = namcs2019sv_df)
|
Check the survey name, survey design variables, and the number of
observations to verify that it all looks correct.
For this example, we do want to turn on certain NCHS-specific
options, such as identifying low-precision estimates. If you do not care
about identifying low-precision estimates, you can skip this command. To
turn on the NCHS-specific options:
set_opts(mode = "NCHS")
## * Mode: NCHS.
Table 1
Counts and percentages
This table shows the overall estimated count as well as the counts
and percentages by type of doctor, physician specialty, and metropolitan
statistical area.
The variables that are necessary for creating this table are already
in the survey, making the commands very straightforward.
Total {NAMCS 2019 PUF}
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
8,250
|
1,036,484
|
48,836
|
945,014
|
1,136,809
|
tab("MDDO", "SPECCAT", "MSA")
Type of doctor (MD or DO) {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
M.D. - Doctor of Medicine
|
7,498
|
980,280
|
48,388
|
889,842
|
1,079,910
|
94.6
|
0.7
|
93.1
|
95.8
|
D.O. - Doctor of Osteopathy
|
752
|
56,204
|
6,602
|
44,597
|
70,832
|
5.4
|
0.7
|
4.2
|
6.9
|
Type of specialty (Primary, Medical, Surgical) {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Primary care specialty
|
2,993
|
521,466
|
31,136
|
463,840
|
586,252
|
50.3
|
2.6
|
45.1
|
55.5
|
Surgical care specialty
|
3,050
|
214,832
|
31,110
|
161,661
|
285,490
|
20.7
|
3.0
|
15.1
|
27.3
|
Medical care specialty
|
2,207
|
300,186
|
43,497
|
225,806
|
399,067
|
29.0
|
3.6
|
22.1
|
36.6
|
Metropolitan Statistical Area Status of physician location {NAMCS 2019
PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
MSA (Metropolitan Statistical Area)
|
7,496
|
973,676
|
50,515
|
879,490
|
1,077,947
|
93.9
|
1.7
|
89.6
|
96.8
|
Non-MSA
|
754
|
62,809
|
17,549
|
36,249
|
108,830
|
6.1
|
1.7
|
3.2
|
10.4
|
Rates
The published table also shows several rates. To calculate rates, in
addition to the survey, we need a source of information with population
estimates. You would typically use a function such as
read.csv()
to load the population estimates and get them
into the correct format. The surveytable
package comes with
an object called uspop2019
that contains several population
estimates for use in these examples.
class(uspop2019)
## [1] "list"
names(uspop2019)
## [1] "total" "MSA" "AGER" "Age group" "SEX"
## [6] "AGER x SEX" "Age group 5"
Here is the overall population estimate:
uspop2019$total
## [1] 323186697
Once we have the overall population estimate, the overall rate
is:
Total (rate per 100 population) {NAMCS 2019 PUF}
|
n
|
Rate
|
SE
|
LL
|
UL
|
8,250
|
321
|
15
|
292
|
352
|
To calculate the rates for a particular variable, we need to provide
a data frame with a variable called Level
that matches the
levels of the variable in the survey, and a variable called
Population
that gives the population size (which is assumed
to be a constant rather than a random variable).
For MSA
, we can see the levels of the variables just by
using the tab()
command, just as we did above. Thus, to
calculate rates, we need a data frame as follows:
uspop2019$MSA
## Level Population
## 1 MSA (Metropolitan Statistical Area) 277229518
## 2 Non-MSA 45957179
Now that we have the appropriate population estimates, the rate
is:
Metropolitan Statistical Area Status of physician location (rate per 100
population) {NAMCS 2019 PUF}
|
Level
|
n
|
Rate
|
SE
|
LL
|
UL
|
MSA (Metropolitan Statistical Area)
|
7,496
|
351
|
18
|
317
|
389
|
Non-MSA
|
754
|
137
|
38
|
79
|
237
|
We can also calculate rates of a specific variable based on the
entire population:
tab_rate("MDDO", uspop2019$total)
## * Rate based on the entire population.
Type of doctor (MD or DO) (rate per 100 population) {NAMCS 2019 PUF}
|
Level
|
n
|
Rate
|
SE
|
LL
|
UL
|
M.D. - Doctor of Medicine
|
7,498
|
303
|
15
|
275
|
334
|
D.O. - Doctor of Osteopathy
|
752
|
17
|
2
|
14
|
22
|
tab_rate("SPECCAT", uspop2019$total)
## * Rate based on the entire population.
Type of specialty (Primary, Medical, Surgical) (rate per 100 population)
{NAMCS 2019 PUF}
|
Level
|
n
|
Rate
|
SE
|
LL
|
UL
|
Primary care specialty
|
2,993
|
161
|
10
|
144
|
181
|
Surgical care specialty
|
3,050
|
66
|
10
|
50
|
88
|
Medical care specialty
|
2,207
|
93
|
14
|
70
|
124
|
Table 3
Counts and percentages
This table presents estimates for each age group, as well as for each
age group by sex.
Variables beginning with ‘age’ {NAMCS 2019 PUF}
|
Variable
|
Class
|
Long name
|
AGE
|
numeric
|
Patient age in years (raw - use caution)
|
AGER
|
factor
|
Patient age recode
|
The survey has a couple of relevant age-related variables.
AGE
is the patient age in years. AGER
is a
categorical variable based on AGE
. However, for this table,
in addition to AGER
, we need another age group variable,
with different age categories. We create it using the
var_cut
function.
var_cut("Age group", "AGE"
, c(-Inf, 0, 4, 14, 64, Inf)
, c("Under 1", "1-4", "5-14", "15-64", "65 and over") )
Now that we’ve created the Age group
variable, we can
create the tables:
tab("AGER", "Age group", "SEX")
Patient age recode {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Under 15 years
|
887
|
117,917
|
14,097
|
93,229
|
149,142
|
11.4
|
1.3
|
8.9
|
14.2
|
15-24 years
|
542
|
64,856
|
7,018
|
52,387
|
80,292
|
6.3
|
0.6
|
5.1
|
7.5
|
25-44 years
|
1,435
|
170,271
|
13,966
|
144,925
|
200,049
|
16.4
|
1.1
|
14.3
|
18.8
|
45-64 years
|
2,283
|
309,506
|
23,290
|
266,994
|
358,787
|
29.9
|
1.4
|
27.2
|
32.6
|
65-74 years
|
1,661
|
206,866
|
14,366
|
180,481
|
237,109
|
20.0
|
1.2
|
17.6
|
22.5
|
75 years and over
|
1,442
|
167,069
|
15,179
|
139,746
|
199,735
|
16.1
|
1.3
|
13.7
|
18.8
|
Age group {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Under 1
|
203
|
31,148
|
5,282
|
22,269
|
43,566
|
3.0
|
0.5
|
2.1
|
4.1
|
1-4
|
281
|
38,240
|
5,444
|
28,864
|
50,662
|
3.7
|
0.5
|
2.7
|
4.8
|
5-14
|
403
|
48,529
|
5,741
|
38,430
|
61,282
|
4.7
|
0.5
|
3.7
|
5.9
|
15-64
|
4,260
|
544,632
|
36,082
|
478,254
|
620,223
|
52.5
|
2.0
|
48.6
|
56.5
|
65 and over
|
3,103
|
373,935
|
24,523
|
328,777
|
425,296
|
36.1
|
1.9
|
32.3
|
40.0
|
Patient sex {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Female
|
4,609
|
605,045
|
34,866
|
540,377
|
677,452
|
58.4
|
1.9
|
54.6
|
62.1
|
Male
|
3,641
|
431,439
|
27,664
|
380,436
|
489,280
|
41.6
|
1.9
|
37.9
|
45.4
|
(Patient age recode) x (Patient sex) {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Under 15 years: Female
|
434
|
59,958
|
7,206
|
47,318
|
75,974
|
5.8
|
0.7
|
4.5
|
7.3
|
15-24 years: Female
|
346
|
41,128
|
4,532
|
33,066
|
51,156
|
4.0
|
0.4
|
3.2
|
4.9
|
25-44 years: Female
|
923
|
113,708
|
11,461
|
93,256
|
138,646
|
11.0
|
1.0
|
9.0
|
13.2
|
45-64 years: Female
|
1,253
|
175,978
|
16,009
|
147,153
|
210,450
|
17.0
|
1.1
|
14.8
|
19.3
|
65-74 years: Female
|
891
|
120,099
|
11,066
|
100,171
|
143,992
|
11.6
|
1.0
|
9.7
|
13.7
|
75 years and over: Female
|
762
|
94,173
|
11,085
|
74,682
|
118,751
|
9.1
|
0.9
|
7.3
|
11.1
|
Under 15 years: Male
|
453
|
57,959
|
7,728
|
44,570
|
75,371
|
5.6
|
0.7
|
4.3
|
7.2
|
15-24 years: Male
|
196
|
23,728
|
4,344
|
16,457
|
34,210
|
2.3
|
0.4
|
1.6
|
3.2
|
25-44 years: Male
|
512
|
56,562
|
7,277
|
43,861
|
72,942
|
5.5
|
0.6
|
4.3
|
6.8
|
45-64 years: Male
|
1,030
|
133,528
|
12,956
|
110,319
|
161,619
|
12.9
|
1.0
|
10.9
|
15.1
|
65-74 years: Male
|
770
|
86,766
|
6,767
|
74,409
|
101,176
|
8.4
|
0.6
|
7.2
|
9.7
|
75 years and over: Male
|
680
|
72,896
|
6,661
|
60,872
|
87,296
|
7.0
|
0.6
|
5.9
|
8.3
|
Rates
Patient age recode (rate per 100 population) {NAMCS 2019 PUF}
|
Level
|
n
|
Rate
|
SE
|
LL
|
UL
|
Under 15 years
|
887
|
195
|
23
|
154
|
246
|
15-24 years
|
542
|
156
|
17
|
126
|
192
|
25-44 years
|
1,435
|
199
|
16
|
169
|
234
|
45-64 years
|
2,283
|
375
|
28
|
323
|
435
|
65-74 years
|
1,661
|
662
|
46
|
577
|
758
|
75 years and over
|
1,442
|
776
|
70
|
649
|
928
|
tab_rate("Age group", uspop2019$`Age group`)
## * Population for some levels not defined: 15-64
Age group (rate per 100 population) {NAMCS 2019 PUF}
|
Level
|
n
|
Rate
|
SE
|
LL
|
UL
|
Under 1
|
203
|
824
|
140
|
589
|
1,152
|
1-4
|
281
|
242
|
34
|
183
|
321
|
5-14
|
403
|
118
|
14
|
94
|
150
|
15-64
|
4,260
|
NA
|
NA
|
NA
|
NA
|
65 and over
|
3,103
|
708
|
46
|
623
|
806
|
Patient sex (rate per 100 population) {NAMCS 2019 PUF}
|
Level
|
n
|
Rate
|
SE
|
LL
|
UL
|
Female
|
4,609
|
366
|
21
|
327
|
410
|
Male
|
3,641
|
273
|
18
|
241
|
310
|
To calculate the rates for one variable (AGER
) by
another variable (SEX
), we need population estimates in the
following format:
uspop2019$`AGER x SEX`
## Level Subset Population
## 1 Under 15 years Female 29604762
## 2 15-24 years Female 20730118
## 3 25-44 years Female 43192143
## 4 45-64 years Female 42508901
## 5 65-74 years Female 16673240
## 6 75 years and over Female 12421444
## 7 Under 15 years Male 30921894
## 8 15-24 years Male 20988582
## 9 25-44 years Male 42407267
## 10 45-64 years Male 40053148
## 11 65-74 years Male 14586962
## 12 75 years and over Male 9098236
Once we have these population estimates, the rates are:
Patient age recode (Patient sex = Female) (rate per 100 population)
{NAMCS 2019 PUF}
|
Level
|
n
|
Rate
|
SE
|
LL
|
UL
|
Under 15 years
|
434
|
202
|
24
|
160
|
257
|
15-24 years
|
346
|
198
|
22
|
160
|
247
|
25-44 years
|
923
|
263
|
26
|
216
|
321
|
45-64 years
|
1,253
|
414
|
38
|
346
|
495
|
65-74 years
|
891
|
720
|
66
|
601
|
864
|
75 years and over
|
762
|
758
|
89
|
601
|
956
|
Patient age recode (Patient sex = Male) (rate per 100 population) {NAMCS
2019 PUF}
|
Level
|
n
|
Rate
|
SE
|
LL
|
UL
|
Under 15 years
|
453
|
187
|
25
|
144
|
244
|
15-24 years
|
196
|
113
|
21
|
78
|
163
|
25-44 years
|
512
|
133
|
17
|
103
|
172
|
45-64 years
|
1,030
|
333
|
32
|
275
|
404
|
65-74 years
|
770
|
595
|
46
|
510
|
694
|
75 years and over
|
680
|
801
|
73
|
669
|
960
|
Table 5
This table gives the expected sources of payment. We use the
PAY*
variables to create several new variables that are
required by the table. Note that the PAY*
variables are
logical (TRUE
or FALSE
), which simplifies the
workflow. (The survey was imported into R using the
importsurvey
package, which automatically detects binary
variables and imports them as logical variables.)
#
var_all("Medicare and Medicaid", c("PAYMCARE", "PAYMCAID"))
#
var_any("Payment used", c("PAYPRIV", "PAYMCARE", "PAYMCAID"
, "PAYWKCMP", "PAYOTH", "PAYDK"))
var_not("No other payment used", "Payment used")
var_all("Self-pay", c("PAYSELF", "No other payment used"))
var_all("No charge", c("PAYNOCHG", "No other payment used"))
var_any("No insurance", c("Self-pay", "No charge"))
#
var_case("No pay", "NOPAY", "No categories marked")
var_any("Unknown or blank", c("PAYDK", "No pay"))
##
tab("PAYPRIV", "PAYMCARE", "PAYMCAID", "Medicare and Medicaid"
, "No insurance", "Self-pay", "No charge"
, "PAYWKCMP", "PAYOTH", "Unknown or blank")
Expected source of payment for visit: Private insurance {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
FALSE
|
3,395
|
436,331
|
38,863
|
366,358
|
519,669
|
42.1
|
2.8
|
36.5
|
47.8
|
TRUE
|
4,855
|
600,153
|
35,912
|
533,694
|
674,888
|
57.9
|
2.8
|
52.2
|
63.5
|
Expected source of payment for visit: Medicare {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
FALSE
|
5,539
|
717,764
|
40,947
|
641,784
|
802,739
|
69.2
|
2
|
65.1
|
73.2
|
TRUE
|
2,711
|
318,721
|
24,814
|
273,557
|
371,341
|
30.8
|
2
|
26.8
|
34.9
|
Expected source of payment for visit: Medicaid or CHIP or other
state-based program {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
FALSE
|
7,223
|
894,590
|
45,335
|
809,962
|
988,061
|
86.3
|
1.7
|
82.6
|
89.5
|
TRUE
|
1,027
|
141,894
|
19,039
|
108,992
|
184,728
|
13.7
|
1.7
|
10.5
|
17.4
|
Medicare and Medicaid {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
FALSE
|
8,126
|
1,016,202
|
47,395
|
927,389
|
1,113,520
|
98
|
0.5
|
96.9
|
98.9
|
TRUE
|
124
|
20,282
|
5,177
|
12,120
|
33,941
|
2
|
0.5
|
1.1
|
3.1
|
No insurance {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Flags
|
FALSE
|
7,945
|
994,579
|
50,446
|
900,421
|
1,098,583
|
96
|
2.2
|
89.1
|
99.1
|
Pc
|
TRUE
|
305
|
41,906
|
22,733
|
14,133
|
124,256
|
4
|
2.2
|
0.9
|
10.9
|
Cx Px
|
Self-pay {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Flags
|
FALSE
|
7,951
|
994,770
|
50,446
|
900,611
|
1,098,772
|
96
|
2.2
|
89.1
|
99.1
|
Pc
|
TRUE
|
299
|
41,715
|
22,734
|
13,995
|
124,337
|
4
|
2.2
|
0.9
|
10.9
|
Cx Px
|
No charge {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Flags
|
FALSE
|
8,243
|
1,036,081
|
48,837
|
944,610
|
1,136,409
|
100
|
0
|
99.9
|
100.0
|
|
TRUE
|
7
|
404
|
238
|
38
|
4,293
|
0
|
0
|
0.0
|
0.1
|
Cx
|
Expected source of payment for visit: Workers Compensation {NAMCS 2019
PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Flags
|
FALSE
|
8,148
|
994,493
|
47,949
|
904,779
|
1,093,103
|
95.9
|
3.2
|
84.1
|
99.7
|
Pc
|
TRUE
|
102
|
41,991
|
33,472
|
8,413
|
209,596
|
4.1
|
3.2
|
0.3
|
15.9
|
Cx Px
|
Expected source of payment for visit: Other {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
FALSE
|
8,077
|
1,017,442
|
47,898
|
927,725
|
1,115,836
|
98.2
|
0.3
|
97.5
|
98.7
|
TRUE
|
173
|
19,042
|
3,156
|
13,641
|
26,581
|
1.8
|
0.3
|
1.3
|
2.5
|
Unknown or blank {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
FALSE
|
7,879
|
1,004,918
|
49,232
|
912,871
|
1,106,245
|
97
|
0.6
|
95.4
|
98.1
|
TRUE
|
371
|
31,567
|
6,533
|
20,907
|
47,661
|
3
|
0.6
|
1.9
|
4.6
|
Check the presentation standards flags! Under NCHS presentation
standards rules, some of these estimates should not be shown.
Table 6
This table shows the primary care provider and referral status, by
prior-visit status.
In the table, the “Unknown” and “Blank” values are collapsed into a
single value. We can collapse two or more levels of a factor into a
single level using the var_collapse
function.
var_collapse("PRIMCARE", "Unknown if PCP", c("Unknown", "Blank"))
var_collapse("REFER", "Unknown if referred", c("Unknown", "Blank"))
Now, for the table:
tab("PRIMCARE", "REFER", "SENBEFOR")
Are you the patient’s primary care provider? {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Unknown if PCP
|
316
|
40,669
|
9,479
|
25,619
|
64,560
|
3.9
|
0.9
|
2.4
|
6.1
|
Yes
|
2,278
|
383,481
|
28,555
|
331,362
|
443,798
|
37.0
|
2.6
|
31.9
|
42.3
|
No
|
5,656
|
612,335
|
43,282
|
533,050
|
703,413
|
59.1
|
2.5
|
53.9
|
64.1
|
Was patient referred for visit? {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Unknown if referred
|
874
|
87,560
|
14,725
|
62,867
|
121,951
|
8.4
|
1.5
|
5.7
|
11.9
|
Not applicable
|
2,278
|
383,481
|
28,555
|
331,362
|
443,798
|
37.0
|
2.6
|
31.9
|
42.3
|
Yes
|
2,134
|
264,044
|
34,909
|
203,623
|
342,394
|
25.5
|
2.8
|
20.1
|
31.5
|
No
|
2,964
|
301,400
|
30,918
|
246,436
|
368,622
|
29.1
|
2.6
|
24.1
|
34.4
|
Has this patient been seen in your practice before? {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Yes, established patient
|
6,771
|
862,626
|
43,142
|
782,038
|
951,518
|
83.2
|
1.4
|
80.3
|
85.8
|
No, new patient
|
1,479
|
173,859
|
16,338
|
144,536
|
209,130
|
16.8
|
1.4
|
14.2
|
19.7
|
The percentages within each subset that is defined by
SENBEFOR
add up to 100% – for this reason, we want to use
tab_subset()
, not tab_cross()
.
Are you the patient’s primary care provider? (Has this patient been seen
in your practice before? = Yes, established patient) {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Unknown if PCP
|
236
|
28,494
|
7,930
|
16,343
|
49,679
|
3.3
|
0.9
|
1.8
|
5.6
|
Yes
|
2,127
|
359,164
|
26,752
|
310,334
|
415,677
|
41.6
|
2.8
|
36.2
|
47.3
|
No
|
4,408
|
474,967
|
36,421
|
408,617
|
552,092
|
55.1
|
2.7
|
49.6
|
60.4
|
Are you the patient’s primary care provider? (Has this patient been seen
in your practice before? = No, new patient) {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Flags
|
Unknown if PCP
|
80
|
12,174
|
4,817
|
5,488
|
27,005
|
7
|
2.6
|
2.8
|
14.0
|
Cx Px
|
Yes
|
151
|
24,317
|
4,402
|
16,964
|
34,855
|
14
|
2.6
|
9.2
|
20.0
|
|
No
|
1,248
|
137,368
|
14,568
|
111,497
|
169,241
|
79
|
3.2
|
71.8
|
85.1
|
|
Was patient referred for visit? (Has this patient been seen in your
practice before? = Yes, established patient) {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Unknown if referred
|
606
|
58,208
|
11,757
|
39,052
|
86,761
|
6.7
|
1.4
|
4.2
|
10.1
|
Not applicable
|
2,127
|
359,164
|
26,752
|
310,334
|
415,677
|
41.6
|
2.8
|
36.2
|
47.3
|
Yes
|
1,324
|
172,899
|
28,658
|
124,751
|
239,629
|
20.0
|
2.9
|
14.7
|
26.4
|
No
|
2,714
|
272,354
|
27,253
|
223,783
|
331,468
|
31.6
|
2.7
|
26.3
|
37.3
|
Was patient referred for visit? (Has this patient been seen in your
practice before? = No, new patient) {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Unknown if referred
|
268
|
29,351
|
6,343
|
19,106
|
45,091
|
16.9
|
3.5
|
10.6
|
25.0
|
Not applicable
|
151
|
24,317
|
4,402
|
16,964
|
34,855
|
14.0
|
2.6
|
9.2
|
20.0
|
Yes
|
810
|
91,145
|
13,090
|
68,656
|
121,000
|
52.4
|
5.1
|
41.9
|
62.8
|
No
|
250
|
29,046
|
7,757
|
17,084
|
49,382
|
16.7
|
4.0
|
9.6
|
26.2
|
Table 11
This table shows the same information as Table 3, but only for
preventive care visits. That is, estimates for each age group, as well
as for each age group by sex, but only for preventive care visits.
Let’s create Age group
from AGE
and cross
AGER
and SEX
to create a variable called
Age x Sex
:
var_cut("Age group", "AGE"
, c(-Inf, 0, 4, 14, 64, Inf)
, c("Under 1", "1-4", "5-14", "15-64", "65 and over") )
## Warning in var_cut("Age group", "AGE", c(-Inf, 0, 4, 14, 64, Inf), c("Under 1",
## : Age group: overwriting a variable that already exists.
var_cross("Age x Sex", "AGER", "SEX")
To see the possible values of MAJOR
(Major reason for
this visit), and to estimate the total count for preventive care
visits:
Major reason for this visit {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Blank
|
175
|
15,887
|
3,354
|
10,335
|
24,419
|
1.5
|
0.3
|
1.0
|
2.3
|
New problem (less than 3 mos. onset)
|
2,193
|
275,014
|
19,691
|
238,955
|
316,514
|
26.5
|
1.5
|
23.7
|
29.5
|
Chronic problem, routine
|
2,861
|
380,910
|
35,080
|
317,916
|
456,386
|
36.8
|
2.5
|
31.8
|
41.9
|
Chronic problem, flare-up
|
635
|
74,017
|
9,329
|
57,706
|
94,939
|
7.1
|
0.9
|
5.5
|
9.1
|
Pre-surgery
|
159
|
12,864
|
2,151
|
9,188
|
18,010
|
1.2
|
0.2
|
0.9
|
1.7
|
Post-surgery
|
659
|
54,170
|
6,749
|
42,350
|
69,289
|
5.2
|
0.7
|
4.0
|
6.7
|
Preventive care
|
1,568
|
223,624
|
18,520
|
190,068
|
263,103
|
21.6
|
1.7
|
18.3
|
25.1
|
To create the tables of age, sex, and their interaction, and limit
them to only the preventive care visits:
Patient age recode (Major reason for this visit = Preventive care)
{NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Under 15 years
|
300
|
50,701
|
8,556
|
36,352
|
70,714
|
22.7
|
3.5
|
16.1
|
30.4
|
15-24 years
|
121
|
18,196
|
2,889
|
13,246
|
24,996
|
8.1
|
1.2
|
5.9
|
10.9
|
25-44 years
|
370
|
50,573
|
6,835
|
38,749
|
66,005
|
22.6
|
2.5
|
17.8
|
28.0
|
45-64 years
|
355
|
53,805
|
9,478
|
37,982
|
76,218
|
24.1
|
3.2
|
17.9
|
31.1
|
65-74 years
|
225
|
27,985
|
4,669
|
20,073
|
39,017
|
12.5
|
1.8
|
9.2
|
16.5
|
75 years and over
|
197
|
22,363
|
3,805
|
15,925
|
31,404
|
10.0
|
1.7
|
6.9
|
13.8
|
tab_subset("Age group", "MAJOR", "Preventive care")
Age group (Major reason for this visit = Preventive care) {NAMCS 2019
PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Under 1
|
118
|
19,094
|
3,996
|
12,601
|
28,932
|
8.5
|
1.7
|
5.4
|
12.6
|
1-4
|
86
|
14,819
|
3,149
|
9,676
|
22,695
|
6.6
|
1.3
|
4.3
|
9.7
|
5-14
|
96
|
16,788
|
3,524
|
11,035
|
25,542
|
7.5
|
1.5
|
4.9
|
11.0
|
15-64
|
846
|
122,574
|
13,515
|
98,688
|
152,242
|
54.8
|
3.3
|
48.1
|
61.4
|
65 and over
|
422
|
50,349
|
6,451
|
39,083
|
64,861
|
22.5
|
2.4
|
17.8
|
27.8
|
Patient sex (Major reason for this visit = Preventive care) {NAMCS 2019
PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Female
|
1,014
|
139,091
|
11,845
|
117,664
|
164,421
|
62.2
|
2.9
|
56.2
|
68.0
|
Male
|
554
|
84,532
|
10,594
|
66,039
|
108,204
|
37.8
|
2.9
|
32.0
|
43.8
|
tab_subset("Age x Sex", "MAJOR", "Preventive care")
Age x Sex (Major reason for this visit = Preventive care) {NAMCS 2019
PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Under 15 years: Female
|
157
|
28,138
|
4,766
|
20,106
|
39,378
|
12.6
|
2.0
|
8.9
|
17.1
|
15-24 years: Female
|
96
|
12,866
|
2,336
|
8,936
|
18,525
|
5.8
|
1.0
|
3.9
|
8.1
|
25-44 years: Female
|
305
|
40,612
|
6,177
|
30,087
|
54,819
|
18.2
|
2.5
|
13.5
|
23.7
|
45-64 years: Female
|
233
|
31,373
|
4,986
|
22,889
|
43,001
|
14.0
|
1.8
|
10.7
|
17.9
|
65-74 years: Female
|
119
|
13,842
|
2,948
|
9,006
|
21,275
|
6.2
|
1.2
|
4.1
|
9.0
|
75 years and over: Female
|
104
|
12,259
|
2,228
|
8,497
|
17,687
|
5.5
|
1.0
|
3.6
|
7.9
|
Under 15 years: Male
|
143
|
22,563
|
4,501
|
15,195
|
33,505
|
10.1
|
1.8
|
6.7
|
14.4
|
15-24 years: Male
|
25
|
5,330
|
1,615
|
2,751
|
10,328
|
2.4
|
0.7
|
1.2
|
4.3
|
25-44 years: Male
|
65
|
9,961
|
2,607
|
5,849
|
16,964
|
4.5
|
1.1
|
2.6
|
7.1
|
45-64 years: Male
|
122
|
22,432
|
5,911
|
13,196
|
38,130
|
10.0
|
2.3
|
6.0
|
15.5
|
65-74 years: Male
|
106
|
14,143
|
2,611
|
9,716
|
20,587
|
6.3
|
1.0
|
4.4
|
8.7
|
75 years and over: Male
|
93
|
10,104
|
2,704
|
5,828
|
17,518
|
4.5
|
1.2
|
2.5
|
7.4
|
As each of the above commands is similar, and differs only in the
first variable that is passed to the tab_subset()
function,
this code can be streamlined with a for
loop:
for (vr in c("AGER", "Age group", "SEX", "Age x Sex")) {
print( tab_subset(vr, "MAJOR", "Preventive care") )
}
Patient age recode (Major reason for this visit = Preventive care)
{NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Under 15 years
|
300
|
50,701
|
8,556
|
36,352
|
70,714
|
22.7
|
3.5
|
16.1
|
30.4
|
15-24 years
|
121
|
18,196
|
2,889
|
13,246
|
24,996
|
8.1
|
1.2
|
5.9
|
10.9
|
25-44 years
|
370
|
50,573
|
6,835
|
38,749
|
66,005
|
22.6
|
2.5
|
17.8
|
28.0
|
45-64 years
|
355
|
53,805
|
9,478
|
37,982
|
76,218
|
24.1
|
3.2
|
17.9
|
31.1
|
65-74 years
|
225
|
27,985
|
4,669
|
20,073
|
39,017
|
12.5
|
1.8
|
9.2
|
16.5
|
75 years and over
|
197
|
22,363
|
3,805
|
15,925
|
31,404
|
10.0
|
1.7
|
6.9
|
13.8
|
Age group (Major reason for this visit = Preventive care) {NAMCS 2019
PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Under 1
|
118
|
19,094
|
3,996
|
12,601
|
28,932
|
8.5
|
1.7
|
5.4
|
12.6
|
1-4
|
86
|
14,819
|
3,149
|
9,676
|
22,695
|
6.6
|
1.3
|
4.3
|
9.7
|
5-14
|
96
|
16,788
|
3,524
|
11,035
|
25,542
|
7.5
|
1.5
|
4.9
|
11.0
|
15-64
|
846
|
122,574
|
13,515
|
98,688
|
152,242
|
54.8
|
3.3
|
48.1
|
61.4
|
65 and over
|
422
|
50,349
|
6,451
|
39,083
|
64,861
|
22.5
|
2.4
|
17.8
|
27.8
|
Patient sex (Major reason for this visit = Preventive care) {NAMCS 2019
PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Female
|
1,014
|
139,091
|
11,845
|
117,664
|
164,421
|
62.2
|
2.9
|
56.2
|
68.0
|
Male
|
554
|
84,532
|
10,594
|
66,039
|
108,204
|
37.8
|
2.9
|
32.0
|
43.8
|
Age x Sex (Major reason for this visit = Preventive care) {NAMCS 2019
PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Under 15 years: Female
|
157
|
28,138
|
4,766
|
20,106
|
39,378
|
12.6
|
2.0
|
8.9
|
17.1
|
15-24 years: Female
|
96
|
12,866
|
2,336
|
8,936
|
18,525
|
5.8
|
1.0
|
3.9
|
8.1
|
25-44 years: Female
|
305
|
40,612
|
6,177
|
30,087
|
54,819
|
18.2
|
2.5
|
13.5
|
23.7
|
45-64 years: Female
|
233
|
31,373
|
4,986
|
22,889
|
43,001
|
14.0
|
1.8
|
10.7
|
17.9
|
65-74 years: Female
|
119
|
13,842
|
2,948
|
9,006
|
21,275
|
6.2
|
1.2
|
4.1
|
9.0
|
75 years and over: Female
|
104
|
12,259
|
2,228
|
8,497
|
17,687
|
5.5
|
1.0
|
3.6
|
7.9
|
Under 15 years: Male
|
143
|
22,563
|
4,501
|
15,195
|
33,505
|
10.1
|
1.8
|
6.7
|
14.4
|
15-24 years: Male
|
25
|
5,330
|
1,615
|
2,751
|
10,328
|
2.4
|
0.7
|
1.2
|
4.3
|
25-44 years: Male
|
65
|
9,961
|
2,607
|
5,849
|
16,964
|
4.5
|
1.1
|
2.6
|
7.1
|
45-64 years: Male
|
122
|
22,432
|
5,911
|
13,196
|
38,130
|
10.0
|
2.3
|
6.0
|
15.5
|
65-74 years: Male
|
106
|
14,143
|
2,611
|
9,716
|
20,587
|
6.3
|
1.0
|
4.4
|
8.7
|
75 years and over: Male
|
93
|
10,104
|
2,704
|
5,828
|
17,518
|
4.5
|
1.2
|
2.5
|
7.4
|
Note that when called from inside a for
loop, the
print()
function needs to be called explicitly.
More advanced coding
In addition, for each age-sex category, the published table shows the
percentage of preventive care visits made to primary care
physicians.
To calculate these percentages, a slightly more involved
for
loop is needed. Below is the code, followed by an
explanation:
for (vr in c("AGER", "Age group", "SEX", "Age x Sex")) {
var_cross("tmp", "MAJOR", vr)
for (lvl in levels(surveytable:::env$survey$variables[,vr])) {
tab_subset("SPECCAT", "tmp", paste0("Preventive care: ", lvl))
}
}
## Warning in var_cross("tmp", "MAJOR", vr): tmp: overwriting a variable that
## already exists.
## Warning in var_cross("tmp", "MAJOR", vr): tmp: overwriting a variable that
## already exists.
## Warning in var_cross("tmp", "MAJOR", vr): tmp: overwriting a variable that
## already exists.
set_opts(csv = "")
## * Turning off CSV output.
- Since
tab_subset()
is called from within a
for
loop, if we wanted to print to the screen, we would
need to use print( tab_subset(*) )
. Since we don’t want to
print to the screen, a call to print()
is omitted.
- Since so many tables are being produced, the output is being sent to
a CSV file.
- As before, the loop goes through the age, sex, and age / sex
interaction variables, calling each of these variables
vr
.
- MAJOR and
vr
are crossed, with the result stored in a
variable called tmp
.
- Next, the inner loop goes through all levels of
vr
,
calling each of these levels lvl
.
- The code tabulates
SPECCAT
(Type of specialty –
Primary, Medical, Surgical) on a subset in which tmp
(which
is MAJOR
crossed with vr
) is restricted to
"Preventive care: "
followed by lvl
, which is
some level of vr
, such as “Under 15 years” for
AGER
.
- Finally, CSV output is turned off.
If you run this code, all of the tables should be stored in the CSV
file. To give you an idea of what the tables should look like, here is
just one of the tables:
vr = "AGER"
var_cross("tmp", "MAJOR", vr)
## Warning in var_cross("tmp", "MAJOR", vr): tmp: overwriting a variable that
## already exists.
lvl = levels(surveytable:::env$survey$variables[,vr])[1]
tab_subset("SPECCAT", "tmp", paste0("Preventive care: ", lvl))
Type of specialty (Primary, Medical, Surgical) (tmp = Preventive care:
Under 15 years) {NAMCS 2019 PUF}
|
Level
|
n
|
Number (000)
|
SE (000)
|
LL (000)
|
UL (000)
|
Percent
|
SE
|
LL
|
UL
|
Flags
|
Primary care specialty
|
289
|
49,978
|
8,682
|
35,483
|
70,395
|
98.6
|
1.2
|
93.3
|
99.9
|
Pc
|
Surgical care specialty
|
4
|
149
|
74
|
28
|
790
|
0.3
|
0.2
|
0.0
|
1.8
|
R Cx
|
Medical care specialty
|
7
|
574
|
574
|
50
|
6,628
|
1.1
|
1.2
|
0.0
|
7.0
|
Cx Px
|
To match the percentage in the published table, see the “Primary care
specialty” row. Be sure to check the presentation standards flags.