Working with National Crime Victimization Survey Data
Authors
Affiliation
Greg Ridgeway
University of Pennsylvania
Ruth Moyer
University of Pennsylvania
Li Sian Goh
University of Pennsylvania
Published
July 25, 2026
1 Introduction
Many commonly used crime datasets, including the NIBRS data we will encounter in the next set of notes, contain only crimes reported to the police. The National Crime Victimization Survey (NCVS) provides a different perspective by collecting self-reported victimization data. Each year, under the guidance of the Bureau of Justice Statistics, the U.S. Census Bureau interviews a sample of people 12 years old or older about the number and characteristics of crime victimizations they experienced during the prior 6 months.
In 2023, the NCVS completed 226,480 person interviews in 142,028 household interviews. The survey had a 63% response rate for households and an 82% response rate for individuals. Households remain in the sample for \(3\frac{1}{2}\) years, completing interviews every 6 months, in person or by phone, for a total of seven interviews. Current federal estimates put the annual cost at roughly $55M and the uncompensated respondent time at roughly 123,000 hours.
The NCVS contains information about nonfatal personal crimes, such as rape and robbery, as well as property crimes, such as burglary. Additional information about the NCVS can be found at the BJS website. To give a sense of the type of data that the NCVS contains, refer to the Official 2023 BJS Crime Victimization report.
2 Acquiring the NCVS data
The University of Michigan consolidates the NCVS data into a format that is easily accessible in R. We will be using data collected in 2022 and 2023 to assemble a dataset that covers victimizations occurring in 2022. Since respondents are asked about crime in the previous six months, respondents completing surveys in May 2023 will still be reporting about crimes in December 2022.
Why am I not using 2024 or 2025 data? In 2024, BJS used a split-sample design, giving half of the randomly selected households the legacy instrument and half the redesigned instrument. BJS has released the legacy data but has not released the data from the half that received the redesigned instrument. The survey fully transitioned to the redesigned instrument in 2025, but BJS has not announced a release date for those data. Data collection for crimes that occurred in 2025 will continue through June 2026. Data collected in 2026 will probably not be posted until fall 2027.
First, we will download the NCVS 2022 data, ICPSR 38603. Click on Download, select R, save the resulting file (called something like ICPSR_38603-V1.zip), extract the contents of the zipped file to a convenient folder, and give it a more understandable folder name, like NCVS2022. Repeat the process for downloading the NCVS 2023 data, ICPSR 38962. New NCVS data tends to appear in mid-September. Typically we need to wait about nine months to get the results from the previous year.
After unzipping the NCVS files, you will find subfolders called DS0001, DS0002, DS0003, DS0004, and DS0005.
Inside each of these subfolders you will see an R data file with the extension .rda. We will spend most of our attention on the contents of the DS0005 folder, which contains the “incident-level extract file.” In each folder you will also find codebooks in PDF (and EPUB) format. The codebook is as important as it is tedious for understanding what is stored in the NCVS data. You should become familiar with the codebooks as soon as you can.
Let’s start loading these datasets. We will skip the DS0001 subfolder, which contains basic survey information on the targeted addresses. The DS0002 folder contains data on the households included in the survey.
load("NCVS2022/DS0002/38603-0002-Data.rda")load("NCVS2023/DS0002/38962-0002-Data.rda")# and let's give them nicer namesdataHH22 <- da38603.0002dataHH23 <- da38962.0002
V2001 YEARQ IDHH V2003
1 (2) Household record 2022.1 1809000258358302568236125 (221) 2022, 1st quarter
2 (2) Household record 2022.1 1809000258380931568236135 (221) 2022, 1st quarter
3 (2) Household record 2022.1 1809000258543680568236125 (221) 2022, 1st quarter
4 (2) Household record 2022.1 1809000284326166568236135 (221) 2022, 1st quarter
5 (2) Household record 2022.1 1809000284384631568236124 (221) 2022, 1st quarter
6 (2) Household record 2022.1 1809000284459399568236114 (221) 2022, 1st quarter
V2014 V2016 V2018 V2020
1 <NA> (1) Urban <NA> (01) House/apt/flat
2 (1) Owned/being bght (1) Urban <NA> (01) House/apt/flat
3 (1) Owned/being bght (1) Urban <NA> (01) House/apt/flat
4 (1) Owned/being bght (1) Urban <NA> (01) House/apt/flat
5 (1) Owned/being bght (2) Rural (2) Less than $1,000 (01) House/apt/flat
6 (1) Owned/being bght (2) Rural (2) Less than $1,000 (01) House/apt/flat
V2030 V2031 V2032 V2034
1 (218) Type A - Refused (01) White only <NA> <NA>
2 (300) Interviewed hhld <NA> (11) Reference person (2) Widowed
3 (300) Interviewed hhld <NA> (11) Reference person (3) Divorced
4 (300) Interviewed hhld <NA> (11) Reference person (3) Divorced
5 (300) Interviewed hhld <NA> (11) Reference person (1) Married
6 (300) Interviewed hhld <NA> (11) Reference person (2) Widowed
V2036 V2038 V2040A V2127B
1 <NA> <NA> <NA> (3) South
2 (1) Male (42) Bachelor degree (01) White only (3) South
3 (1) Male (42) Bachelor degree (01) White only (3) South
4 (2) Female (43) Master degree (01) White only (3) South
5 (2) Female (28) High school grad (01) White only (3) South
6 (2) Female (28) High school grad (01) White only (3) South
V2129
1 (2) (S)MSA not city
2 (3) Not (S)MSA
3 (1) City of (S)MSA
4 (2) (S)MSA not city
5 (3) Not (S)MSA
6 (2) (S)MSA not city
The 2022 household dataset has 448 columns. Instead of printing out all of them, I just picked out 17 columns here. First off, you can see that the column names are generally not helpful. That is where the codebook comes in handy. The codebook tells you what each variable means.
Somewhat hidden is a table linking column names to English explanations of what is in those columns. You can get to it by extracting the data frame’s “attributes” with attr().
varsHH <- dataHH22 |>attr("variable.labels") |>data.frame() |> tibble::rownames_to_column() |>setNames(c("varname","details")) |>filter(!grepl("^HHREP", varname)) # exclude rows that start with HHREP
Now varsHH has two columns, the first with the column names and the second with the details. Let’s pull up the 17 columns listed before.
varname details
1 V2001 HOUSEHOLD RECORD TYPE
2 YEARQ YEAR AND QUARTER OF INTERVIEW (YYYY.Q)
3 IDHH NCVS ID FOR HOUSEHOLDS
4 V2003 YEAR AND QUARTER IDENTIFICATION NUMBER
5 V2014 TENURE (ORIGINAL)
6 V2016 LAND USE (ORIGINAL)
7 V2018 FARM SALES (ORIGINAL)
8 V2020 TYPE OF LIVING QUARTERS (ORIGINAL)
9 V2030 REASON FOR NONINTERVIEW
10 V2031 RACE OF HH HEAD (TYPE A NONINTERVIEW)
11 V2032 PRINCIPAL PERSON RELATION TO REF PERSON
12 V2034 PRINCIPAL PERSON MARITAL STATUS (CURR)
13 V2036 PRINCIPAL PERSON SEX (ALLOCATED)
14 V2038 PRINCIPAL PERSON EDUCATIONAL ATTAINMENT
15 V2040A PRINCIPAL PERSON RACE RECODE (START 2003 Q1)
16 V2127B REGION - 1990, 2000, 2010 SAMPLE DESIGN (START 1995 Q3)
17 V2129 MSA STATUS
These are much more intelligible descriptions. “SMSA” stands for Standard Metropolitan Statistical Area, an outdated term. Today we simply call them MSAs. Under the current federal standards, an MSA must contain an urban area with at least 50,000 people.
Note the first household record has IDHH equal to 1809000258543680568236125. We can load the respondent “person file” to see who in this household responded.
# loading person-level dataload("NCVS2022/DS0003/38603-0003-Data.rda")load("NCVS2023/DS0003/38962-0003-Data.rda")dataPers22 <- da38603.0003dataPers23 <- da38962.0003# lookup respondents from this householddataPers22 |>filter(IDHH=="1809000258543680568236125") |>select(!starts_with("PERREP")) # drop all the PERREP weight columns
V3001 YEARQ IDHH
1 (3) Person record 2022.1 1809000258543680568236125
2 (3) Person record 2022.3 1809000258543680568236125
IDPER V3002 V3003 V3004
1 180900025854368056823612501 3 (221) 2022, 1st quarter 18
2 180900025854368056823612501 3 (223) 2022, 3rd quarter 18
V3005 V3006 V3008 V3009 V3010 V3011
1 09000258543680568236 1 25 1 1 (1) Personal/self
2 09000258543680568236 1 25 1 1 (2) Telephone/self
V3012 V3013 V3014 V3015 V3016 V3017 V3018
1 (11) Reference person 62 62 (3) Divorced (3) Divorced (1) Male (1) Male
2 (11) Reference person 63 63 (3) Divorced (3) Divorced (1) Male (1) Male
V3019 V3020 V3023A V3024 V3024A V3025 V3026
1 (2) No (42) Bachelor degree (01) White only (2) No (2) No (02) February 12
2 (2) No (42) Bachelor degree (01) White only (2) No (2) No (08) August 31
V3027 V3031 V3032 V3033 V3034 V3035 V3040 V3041 V3042 V3043 V3044 V3045
1 2022 NA 23 NA (2) No NA (2) No NA (2) No NA (2) No NA
2 2022 NA 24 NA (2) No NA (2) No NA (2) No NA (2) No NA
V3046 V3047 V3048 V3049 V3050 V3051 V3052 V3053 V3054 V3055 V3056 V3057
1 (2) No NA (2) No <NA> <NA> <NA> <NA> NA (2) No <NA> <NA> <NA>
2 (2) No NA (2) No <NA> <NA> <NA> <NA> NA (2) No <NA> <NA> <NA>
V3058 V3059 V3060 V3061 V3062 V3063 V3064 V3065 V3066
1 <NA> NA (1) At least 1 entry (0) No (1) Yes (0) No (0) No (0) No (0) No
2 <NA> NA (1) At least 1 entry (1) Yes (0) No (0) No (0) No (0) No (0) No
V3067 V3068 V3069 V3070 V3_V4526H3A V3_V4526H3B V3_V4526H5
1 (0) No (0) No (0) No out of range <NA> (2) No (2) No (2) No
2 (0) No (0) No (0) No out of range <NA> (2) No (2) No (2) No
V3_V4526H4 V3_V4526H6 V3_V4526H7 V3083
1 (2) No (2) No (2) No (1) Yes, born in the United States
2 (2) No (2) No (2) No (1) Yes, born in the United States
V3084 V3085 V3086
1 (2) Straight, that is, not lesbian or gay (1) Male (1) Male
2 (2) Straight, that is, not lesbian or gay (1) Male (1) Male
V3087 V3088 V3089 V3090 V3091 V3092 V3093 V3094
1 (1) Never served in the military <NA> <NA> <NA> <NA> <NA> <NA> <NA>
2 (1) Never served in the military <NA> <NA> <NA> <NA> <NA> <NA> <NA>
V3097A V3098 V3071 V3072 V3073 V3074 V3075
1 <NA> <NA> (1) Yes <NA> <NA> (27) Something else (3) St/cnty/loc govt
2 <NA> <NA> (1) Yes <NA> <NA> (27) Something else (3) St/cnty/loc govt
V3076 V3077 V3078 V3079 V3080 WGTPERCY
1 (1) A city (1) Hhld resp (2) No (4) None above schools 1207.963 603.9816
2 (1) A city (1) Hhld resp (2) No (4) None above schools 1470.257 735.1283
V3081 V3082 PER_TIS PERINTVNUM PINTTYPE_TIS1 PINTTYPE_TIS2
1 0 2022 5 5 <NA> (1) Personal, Self-respondent
2 0 2022 6 6 <NA> (1) Personal, Self-respondent
PINTTYPE_TIS3 PINTTYPE_TIS4
1 (2) Telephone, Self-respondent (2) Telephone, Self-respondent
2 (2) Telephone, Self-respondent (2) Telephone, Self-respondent
PINTTYPE_TIS5 PINTTYPE_TIS6
1 (2) Telephone, Self-respondent (1) Personal, Self-respondent
2 (2) Telephone, Self-respondent (1) Personal, Self-respondent
PINTTYPE_TIS7 PERBOUNDED
1 <NA> (1) Bounded by previous time in sample
2 (2) Telephone, Self-respondent (1) Bounded by previous time in sample
These two rows represent two surveys, six months apart, of the same divorced, 62- to 63-year-old white male. Let’s look up another household.
V3001 YEARQ IDHH
1 (3) Person record 2022.1 1809000284384631568236124
2 (3) Person record 2022.1 1809000284384631568236124
IDPER V3002 V3003 V3004
1 180900028438463156823612401 5 (221) 2022, 1st quarter 18
2 180900028438463156823612402 5 (221) 2022, 1st quarter 18
V3005 V3006 V3008 V3009 V3010 V3011
1 09000284384631568236 1 24 1 1 (2) Telephone/self
2 09000284384631568236 1 24 2 2 (5) Noninterview
V3012 V3013 V3014 V3015 V3016 V3017
1 (11) Reference person 69 69 (1) Married (1) Married (2) Female
2 (01) Husband 60 60 (1) Married (1) Married (1) Male
V3018 V3019 V3020 V3023A V3024 V3024A
1 (2) Female <NA> (28) High school grad (01) White only (2) No (2) No
2 (1) Male (2) No (28) High school grad (01) White only (2) No (2) No
V3025 V3026 V3027 V3031 V3032 V3033 V3034 V3035 V3040 V3041 V3042
1 (02) February 18 2022 NA 9 NA (2) No NA (2) No NA (2) No
2 <NA> NA NA NA NA NA <NA> NA <NA> NA <NA>
V3043 V3044 V3045 V3046 V3047 V3048 V3049 V3050 V3051 V3052 V3053 V3054
1 NA (2) No NA (2) No NA (2) No <NA> <NA> <NA> <NA> NA (2) No
2 NA <NA> NA <NA> NA <NA> <NA> <NA> <NA> <NA> NA <NA>
V3055 V3056 V3057 V3058 V3059 V3060 V3061 V3062 V3063
1 <NA> <NA> <NA> <NA> NA (1) At least 1 entry (1) Yes (0) No (0) No
2 <NA> <NA> <NA> <NA> NA <NA> <NA> <NA> <NA>
V3064 V3065 V3066 V3067 V3068 V3069 V3070 V3_V4526H3A
1 (0) No (0) No (0) No (0) No (0) No (0) No out of range <NA> (1) Yes
2 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
V3_V4526H3B V3_V4526H5 V3_V4526H4 V3_V4526H6 V3_V4526H7
1 (2) No (2) No (2) No (2) No (2) No
2 <NA> <NA> <NA> <NA> <NA>
V3083 V3084
1 (1) Yes, born in the United States (2) Straight, that is, not lesbian or gay
2 <NA> <NA>
V3085 V3086 V3087 V3088 V3089 V3090
1 (2) Female (2) Female (1) Never served in the military <NA> <NA> <NA>
2 <NA> <NA> <NA> <NA> <NA> <NA>
V3091 V3092 V3093 V3094 V3097A V3098 V3071 V3072 V3073 V3074
1 <NA> <NA> <NA> <NA> <NA> <NA> (1) Yes <NA> <NA> (27) Something else
2 <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
V3075 V3076 V3077 V3078
1 (1) Priv company (3) Rural area (1) Hhld resp (2) No
2 <NA> <NA> (0) Not hhld resp <NA>
V3079 V3080 WGTPERCY V3081 V3082 PER_TIS PERINTVNUM
1 (4) None above schools 1070.377 535.1885 0 2022 7 7
2 (4) None above schools 0.000 0.0000 0 2022 7 6
PINTTYPE_TIS1 PINTTYPE_TIS2
1 (2) Telephone, Self-respondent (2) Telephone, Self-respondent
2 (4) Telephone, Proxy (4) Telephone, Proxy
PINTTYPE_TIS3 PINTTYPE_TIS4
1 (2) Telephone, Self-respondent (2) Telephone, Self-respondent
2 (4) Telephone, Proxy (4) Telephone, Proxy
PINTTYPE_TIS5 PINTTYPE_TIS6
1 (2) Telephone, Self-respondent (2) Telephone, Self-respondent
2 (2) Telephone, Self-respondent (2) Telephone, Self-respondent
PINTTYPE_TIS7 PERBOUNDED
1 (2) Telephone, Self-respondent (1) Bounded by previous time in sample
2 (5) Noninterview (1) Bounded by previous time in sample
These rows represent two surveys occurring at the same time. One is of the reference person, a married white female, and the second is of her husband.
Let’s grab the variable details as we did with the household data.
# Person file also has list of variable detailsvarsPers <- dataPers22 |>attr("variable.labels") |>data.frame() |> tibble::rownames_to_column() |>setNames(c("varname","details")) |>filter(!grepl("^(PERREP|PINTTYPE)", varname))varsPers
varname
1 V3001
2 YEARQ
3 IDHH
4 IDPER
5 V3002
6 V3003
7 V3004
8 V3005
9 V3006
10 V3008
11 V3009
12 V3010
13 V3011
14 V3012
15 V3013
16 V3014
17 V3015
18 V3016
19 V3017
20 V3018
21 V3019
22 V3020
23 V3023A
24 V3024
25 V3024A
26 V3025
27 V3026
28 V3027
29 V3031
30 V3032
31 V3033
32 V3034
33 V3035
34 V3040
35 V3041
36 V3042
37 V3043
38 V3044
39 V3045
40 V3046
41 V3047
42 V3048
43 V3049
44 V3050
45 V3051
46 V3052
47 V3053
48 V3054
49 V3055
50 V3056
51 V3057
52 V3058
53 V3059
54 V3060
55 V3061
56 V3062
57 V3063
58 V3064
59 V3065
60 V3066
61 V3067
62 V3068
63 V3069
64 V3070
65 V3_V4526H3A
66 V3_V4526H3B
67 V3_V4526H5
68 V3_V4526H4
69 V3_V4526H6
70 V3_V4526H7
71 V3083
72 V3084
73 V3085
74 V3086
75 V3087
76 V3088
77 V3089
78 V3090
79 V3091
80 V3092
81 V3093
82 V3094
83 V3097A
84 V3098
85 V3071
86 V3072
87 V3073
88 V3074
89 V3075
90 V3076
91 V3077
92 V3078
93 V3079
94 V3080
95 WGTPERCY
96 V3081
97 V3082
98 PER_TIS
99 PERINTVNUM
100 PERBOUNDED
details
1 PERSON RECORD TYPE
2 YEAR AND QUARTER OF INTERVIEW (YYYY.Q)
3 NCVS ID FOR HOUSEHOLDS
4 NCVS ID FOR PERSONS
5 ICPSR HOUSEHOLD IDENTIFICATION NUMBER
6 YEAR AND QUARTER IDENTIFICATION
7 SAMPLE NUMBER
8 SCRAMBLED CONTROL NUMBER
9 HOUSEHOLD NUMBER
10 PANEL AND ROTATION GROUP
11 PERSON SEQUENCE NUMBER
12 PERSON LINE NUMBER
13 TYPE OF INTERVIEW
14 RELATIONSHIP TO REFERENCE PERSON
15 AGE (ORIGINAL)
16 AGE (ALLOCATED)
17 MARITAL STATUS (CURRENT SURVEY)
18 MARITAL STATUS (PREVIOUS SURVEY)
19 SEX (ORIGINAL)
20 SEX (ALLOCATED)
21 NOW AN ARMED FORCES MEMBER
22 EDUCATIONAL ATTAINMENT
23 RACE RECODE (START 2003 Q1)
24 HISPANIC ORIGIN
25 HISPANIC ORIGIN (ALLOCATED) (START 2014 Q1)
26 MONTH INTERVIEW COMPLETED
27 DAY INTERVIEW COMPLETED
28 YEAR INTERVIEW COMPLETED
29 HOW LONG AT THIS ADDRESS (MONTHS)
30 HOW LONG AT THIS ADDRESS (YEARS)
31 HOW MANY TIMES MOVED IN LAST 5 YEARS
32 SOMETHING STOLEN OR ATTEMPT
33 NO. TIMES SOMETHING STOLEN OR ATTEMPT
34 ATTACK, THREAT, THEFT: LOCATION CUES
35 NO. TIMES ATTACK, LOCATION CUES
36 ATTACK, THREAT: WEAPON & ATTACK CUES
37 NO. TIMES ATTACK, WEAPON CUES
38 STOLEN, ATTACK, THREAT: OFFENDER KNOWN
39 NO. TIMES ATTACK, OFFENDER KNOWN
40 FORCED OR COERCED UNWANTED SEX
41 NO. TIMES UNWANTED SEX
42 CALL POLICE TO REPORT SOMETHING ELSE
43 FIRST INCIDENT
44 SECOND INCIDENT
45 THIRD INCIDENT
46 CHECK B: ATTACK, THREAT, THEFT
47 NO. TIMES ATTACK, THREAT, THEFT
48 THOUGHT CRIME BUT DIDN'T CALL POLICE
49 FIRST INCIDENT
50 SECOND INCIDENT
51 THIRD INCIDENT
52 CHECK C: ATTACK, THREAT, THEFT
53 NO. TIMES ATTACK, THREAT, THEFT
54 LI WHO PRESENT DURING SCREEN QUESTIONS
55 C TELEPHONE INTERVIEW
56 C NO ONE BESIDES RESPONDENT PRESENT
57 C RESPONDENT'S SPOUSE
58 C HH MEMBER(S) 12+, NOT SPOUSE
59 C HH MEMBER(S) UNDER 12
60 C NONHOUSEHOLD MEMBER(S)
61 C SOMEONE PRESENT, CAN'T SAY WHO
62 C DON'T KNOW IF SOMEONE ELSE PRESENT
63 RESIDUE: WHO PRESENT DURING SCREEN
64 DID SELECTED RESPONDENT HELP PROXY
65 ARE YOU DEAF OR DO YOU HAVE SERIOUS DIFFICULTY HEARING? (START 2016 Q3)
66 ARE YOU BLIND OR DO YOU HAVE SERIOUS DIFFICULTY SEEING EVEN WHEN WEARING GLASSES (START 2016 Q3)
67 DIFFICULT: LEARN, REMEMBER, CONCENTRATE (START 2016 Q3)
68 LIMITS PHYSICAL ACTIVITIES (START 2016 Q3)
69 DIFFICULT: DRESSING, BATHING, GET AROUND HOME (START 2016 Q3)
70 DIFFICULT: GO OUTSIDE HOME TO SHOP OR DR OFFICE (START 2016 Q3)
71 CITIZENSHIP STATUS (START 2017 Q1)
72 SEXUAL ORIENTATION (START 2017 Q1)
73 GENDER IDENTITY AT BIRTH (START 2017 Q1)
74 CURRENT GENDER IDENTITY (START 2017 Q1)
75 SERVE ON ACTIVE DUTY (START 2017 Q1)
76 LI: WHEN ON ACTIVE DUTY (START 2017 Q1)
77 C ACTIVE DUTY: SEPTEMBER 2001 (START 2017 Q1)
78 C ACTIVE DUTY: AUGUST 1990 TO AUGUST 2001 (START 2017 Q1)
79 C ACTIVE DUTY: MAY 1975 TO JULY 1990 (START 2017 Q1)
80 C ACTIVE DUTY: VIETNAM ERA (AUGUST 1964 TO APRIL 1975) (START 2017 Q1)
81 C ACTIVE DUTY: FEBRUARY 1955 TO JULY 1964 (START 2017 Q1)
82 C ACTIVE DUTY: KOREAN WAR (JULY 1950 TO JANUARY 1955) (START 2017 Q1)
83 C ACTIVE DUTY: DISCLOSURE RECODE (START 2022 Q1)
84 RESIDUE: ACTIVE DUTY (START 2017 Q1)
85 HAVE JOB OR WORK LAST WEEK
86 HAVE JOB OR WORK IN LAST 6 MONTHS
87 DID JOB/WORK LAST 2 WEEKS OR MORE
88 WHICH BEST DESCRIBES YOUR JOB
89 IS EMPLOYMENT PRIVATE, GOVT OR SELF
90 IS WORK MOSTLY IN CITY, SUBURB, RURAL
91 HOUSEHOLD RESPONDENT
92 EMPLOYED BY A COLLEGE OR UNIVERSITY
93 ATTENDING SCHOOL
94 PERSON WEIGHT
95 ADJUSTED PERSON WEIGHT - COLLECTION YEAR
96 NUMBER OF CRIME INCIDENT REPORTS
97 YEAR IDENTIFICATION (START 1999 Q3)
98 PERSON TIME IN SAMPLE (START 2015 Q1)
99 PERSON INTERVIEW NUMBER (START 2015 Q1)
100 PERSON BOUNDED BY PREVIOUS TIME IN SAMPLE (START 2015 Q1)
There is an incident-level file that we will read in here. We are not going to look at it further, since much of the information in this file is also in the incident extract file.
IDHH IDPER V4014
1 1809010265731899564536114 180901026573189956453611401 (12) December
2 1809040225522254568236115 180904022552225456823611501 (11) November
3 1809213903398449563644234 180921390339844956364423401 (09) September
4 1809240299163750563236135 180924029916375056323613501 (09) September
5 1809243565469154563238115 180924356546915456323811501 (12) December
6 1809243958169129563244125 180924395816912956324412501 (08) August
V4529
1 (31) Burg, force ent
2 (56) Theft $50-$249
3 (56) Theft $50-$249
4 (56) Theft $50-$249
5 (58) Theft value NA
6 (20) Verbal thr aslt
Finally, we will load in the incident extract file and its associated variable details. This extract file merges in household-level and person-level information to the incident-level file, allowing you to connect person-level features with features of the victimizations they report.
Let’s take a look at a few of the reported crime victimizations. Here, I will just pull the respondent’s age, marital status, sex, general location, and crime type.
V3014 V3015 V3018 V4022 V4529
1 56 (3) Divorced (2) Female (3) Same city etc (31) Burg, force ent
2 78 (2) Widowed (2) Female (3) Same city etc (56) Theft $50-$249
3 43 (1) Married (1) Male (3) Same city etc (56) Theft $50-$249
Not all information from the household and person files is in the extract file, but many of the features that are likely to be of interest are there.
Now that the datasets are loaded and renamed, we can remove objects from our working environment that we no longer need. We can use rm() to accomplish this.
Here we are going to create a data frame containing all the reported incidents that occurred in 2022. Take a look at the month and year of the reported crime incidents.
dataExt22 |>count(V4015, V4014)
V4015 V4014 n
1 2021 (07) July 138
2 2021 (08) August 280
3 2021 (09) September 384
4 2021 (10) October 510
5 2021 (11) November 650
6 2021 (12) December 849
7 2022 (01) January 772
8 2022 (02) February 727
9 2022 (03) March 774
10 2022 (04) April 730
11 2022 (05) May 770
12 2022 (06) June 839
13 2022 (07) July 718
14 2022 (08) August 593
15 2022 (09) September 383
16 2022 (10) October 292
17 2022 (11) November 136
dataExt23 |>count(V4015, V4014)
V4015 V4014 n
1 2022 (07) July 175
2 2022 (08) August 253
3 2022 (09) September 364
4 2022 (10) October 524
5 2022 (11) November 674
6 2022 (12) December 859
7 2023 (01) January 753
8 2023 (02) February 681
9 2023 (03) March 699
10 2023 (04) April 688
11 2023 (05) May 738
12 2023 (06) June 760
13 2023 (07) July 721
14 2023 (08) August 573
15 2023 (09) September 447
16 2023 (10) October 273
17 2023 (11) November 142
Note that the 2022 NCVS reports on crimes that occurred in 2022 and 2021. Similarly, the 2023 NCVS reports on crimes that occurred in 2023 and 2022. Remember that the NCVS surveys respondents about victimizations from the prior 6 months, excluding the month of the interview. We are going to stack the 2022 and 2023 incident extract data frames and then filter them to exclude 2021 and 2023.
bind_rows() stacks data frames on top of each other, useful when combining two datasets that have the same structure. First we will check that they have the same columns in them.
identical(names(dataExt22), names(dataExt23))
[1] TRUE
Good so far! Now let’s try to stack them.
dataExt <- dataExt22 |>bind_rows(dataExt23)
Error in `bind_rows()`:
! Can't combine `..1$V2061` <factor<f6015>> and `..2$V2061` <double>.
Hmmm… R is complaining about V2061. Note that it specifically complains that one data frame has V2061 stored as a factor (a categorical variable) and the other one has it stored as a double, a decimal number.
dataExt22 |>count(V2061)
V2061 n
1 (01) 1 8
2 <NA> 9537
dataExt23 |>count(V2061)
V2061 n
1 1 14
2 3 1
3 4 3
4 NA 9306
What is V2061 anyway?
varsExt |>filter(varname=="V2061")
varname details
1 V2061 LINE NO. OF 4TH PROXY RESPONDENT
This reports on who answered on behalf of an unavailable respondent. It is not really important for us, so let’s drop this one by using select(-V2061) on both data frames.
Error in `bind_rows()`:
! Can't combine `..1$V4126` <factor<fb04b>> and `..2$V4126` <double>.
Ughh. Now it is complaining about V4126.
varsExt |>filter(varname=="V4126")
varname details
1 V4126 WHICH INJURY FROM OTHER WEAPON (3RD)
dataExt22 |>count(V4126)
V4126 n
1 (10) Bruises, cuts 3
2 <NA> 9542
dataExt23 |>count(V4126)
V4126 n
1 NA 9324
In the codebook we can find the full question: “Q.33.3 Which injuries were caused by a weapon OTHER than a gun or knife?”. This seems like a potentially interesting question that I probably do not want to discard. The issue is that no 2023 respondent said there was a third weapon that injured them. In 2022 V4126 was stored as a factor, but in 2023, since they are all missing, R defaulted to numeric (double). We can fix this by just telling R to convert the 2023 data into a factor.
Error in `bind_rows()`:
! Can't combine `..1$V4313` <factor<514cc>> and `..2$V4313` <double>.
Dammit! Now it is complaining about V4313. What is the problem with this one? Again we have a problem with 2022 storing as a factor and 2023 storing as a double.
varsExt |>filter(varname=="V4313")
varname details
1 V4313 3RD LINE NO. OF OTHER OWNER THEFT ITEMS
dataExt22 |>count(V4313)
V4313 n
1 (06) 6 2
2 <NA> 9543
dataExt23 |>count(V4313)
V4313 n
1 4 1
2 5 1
3 NA 9322
This column answers “Besides the respondent, which household member(s) owned the (property/money) the offender tried to take?” In 2022, the only responses were missing or #6. In 2023, the responses were missing, 4, or 5. These should be numbers since they are supposed to link to respondents in the same household affected by the theft. The approach I’ll take is to use recode_values(), telling R to change the 2022 “(06) 6” response to a regular 6.
You might have seen this word “Residue” show up before. For the NCVS, BJS records “Residue” when there is a data entry error resulting in an out-of-range code, an incorrect or unusable answer by the respondent, or the absence of an entry for a question that should have been asked. Sometimes you might also see “Out of universe/blank.” This happens when a question is outside the set that a respondent should answer. For example, only victims who report being injured are asked whether they received medical care. All other victims skip the question.
I will solve this issue by recoding the 2023 values to numeric values.
V4357A n
1 1 89
2 2 8
3 3 3
4 997 1
5 998 2
6 NA 18766
Remember that we still have data in here from 2021 and 2023.
table(dataExt$V4015)
2021 2022 2023
2811 9583 6475
We are just going to focus on 2022.
dataExt <- dataExt |>filter(V4015==2022)
Note that BJS official reports generally classify victimizations by the year of the survey and not by the year of the crime. Our 2022 calendar-year dataset combines records carrying collection-year weights from two survey years, so its estimates will not exactly reproduce the official 2022 estimates.
Some respondents report crime victimizations that occurred outside of the United States.
# V4022 - IN WHAT CITY, TOWN, VILLAGE.dataExt |>count(V4022)
V4022 n
1 (1) Outside U.S. 44
2 (2) Not in city etc 67
3 (3) Same city etc 8069
4 (4) Diff city etc 1354
5 (5) Don't know 37
6 (8) Residue 12
The BJS convention is to exclude these crimes in official reports (see 2023 User Guide, page 21).
A sampling weight tells us how many units in the population a sampled record represents. The NCVS interviews a sample of U.S. households and people, so one record in the data may represent hundreds or thousands of victimizations in the population. To estimate a national total, we sum the weights rather than count the rows. To estimate a percentage, we sum the weights for records with the feature of interest and divide by the sum of all the relevant weights. The weights account for the sample design, adjust for nonresponse, and calibrate the sample to known population totals.
The NCVS sampling design has historically emphasized stability and operational continuity, relying heavily on Census Bureau sampling and fieldwork logistics. A 2008 National Academies report noted that the original design gave each household the same probability of selection, even though such a design was not optimal for many uses of the NCVS, and recommended giving housing units higher selection probabilities where victimization rates were higher. At the first stage, the design has generally sampled counties with probabilities approximately proportional to population size, without including a local crime-rate measure. Research suggests that police-reported crime rates and tract-level demographic measures can predict victimization and could improve precision, but those measures are not currently part of the sampling plan. The sampling weights are still essential because selection probabilities vary for other design reasons, and the weights also adjust for nonresponse and calibrate the sample to known population totals.
Constructing the sampling weights is a complex process (see the User Guide “Weights Details” section starting on page 22). The NCVS sampling weights adjust for six factors. From the User Guide:
Base weight: The inverse of the national sampling rate for the stratum of that unit (person or household)
Weighting control: Adjusts for any subsampling due to unexpected events in the field, such as new construction, area segments larger than anticipated, and other deviations from the overall stratum sampling rate
Household noninterview adjustment: Adjusts for nonresponse at the household level by increasing the weights of interviewed households most similar to households not interviewed in terms of race, MSA status of residence, and urban/suburban/rural status of residence. This inflates the weight assigned to interviewed households so that they represent themselves and noninterviewed households. The noninterviewed cases are assigned a weight of zero, excluding them from population estimates
Within-household noninterview adjustment: Adjusts for nonresponse at the person level by increasing the weights of interviewed persons most similar to persons not interviewed in terms of region, age, race, sex, and household composition. The adjustment inflates the weight assigned to completed interviews so that they represent themselves and sampled individuals who were not interviewed. The noninterviewed cases are assigned a weight of zero
First-stage ratio estimate factor: Adjusts for differences between the characteristics of sampled non-self-representing (NSR) primary sampling units (PSUs) and independent measures of the population in NSR PSUs. For self-representing PSUs, this factor is set to 1. The factor adjusts for PSU differences in region, MSA status, urban/suburban/rural status, and racial composition. (PSUs are essentially counties… or a small group of counties.)
Second-stage ratio estimate factor: A poststratification factor defined for each person to adjust for the difference between weighted counts of persons, using the five weight components above, and independent estimates of the number of persons within certain age-by-race-by-sex categories. These independent estimates are based on Census population controls adjusted for the undercount
TipAlways use the sampling weights
Importantly, every population estimate you produce with the NCVS must use the appropriate weights. Use SERIES_WEIGHT for victimization totals and percentages, and use SERIES_IWEIGHT when the unit of interest is a criminal incident. To estimate a victimization rate, divide the weighted number of victimizations by the weighted population at risk. Use person weights for personal crimes (WGTPERCY) and household weights (WGTHHCY) for household property crimes. Even plots and figures intended to describe the U.S. population should use weights. Unweighted tabulations are still useful for checking the data, but they should not be presented as national estimates.
Where you would normally compute a sample mean as \(\frac{\sum x_i}{n}\), the weighted mean is \[
\frac{\sum w_ix_i}{\sum w_i}
\] For a weighted percentage, total all the weights for records with the particular feature and divide by the total weight. For some plots there is not an obvious way to accommodate the sampling weights. In those cases, we can sample with replacement with probabilities proportional to the sampling weights and plot the sampled points.
This chapter focuses on point estimates. To calculate valid standard errors and confidence intervals, you also need to account for the complex sample design. The incident extract includes 160 replicate weights for this purpose, and BJS uses balanced repeated replication with Fay’s method.
For estimating victimization totals in the incident extract, we will focus on two weights. WGTVICCY is the adjusted collection-year victimization weight. It tells us how many victimizations a record represents when that record is counted once. SERIES_WEIGHT begins with WGTVICCY and also accounts for series crimes.
Some crimes happen in a series. For example, a respondent may report regular domestic abuse that happened numerous times over the last six months. Each occurrence of domestic abuse is a victimization, but the BJS convention is to count up to 10 occurrences for crimes reported as a series (2023 User Guide, pages 18-19). For a nonseries crime, SERIES_WEIGHT and WGTVICCY are equal. For a series crime, SERIES_WEIGHT is WGTVICCY multiplied by the reported number of occurrences, capped at 10. If the number of occurrences is unavailable, BJS uses six.
Variable V4016 records the answer to “Altogether, how many times did this type of incident happen during the last 6 months?” and variable V4019 documents “Can you (respondent) recall enough details of each incident to distinguish them from each other?” Note that the coding of V4016 has 997 representing “Don’t know” and 998 representing “Residue.” These are not counts of victimizations. Fortunately, SERIES_WEIGHT already incorporates the series adjustment, so we do not need to change V4016 ourselves.
The ratio of SERIES_WEIGHT to WGTVICCY shows how many victimizations each record contributes after the series adjustment. The ratio is 1 for nonseries crimes and ranges from 2 to 10 for the series crimes shown below.
V4016 V4019 WGTVICCY SERIES_WEIGHT seriesMultiplier
1 7 (2) No (is series) 2315.6980 16209.886 7
2 6 (2) No (is series) 418.0296 2508.178 6
3 6 (2) No (is series) 1899.7567 11398.540 6
4 6 (2) No (is series) 2235.6122 13413.673 6
5 7 (2) No (is series) 1560.4005 10922.804 7
6 30 (2) No (is series) 3059.0421 30590.421 10
NoteExercises
Compare nrow(dataExt), sum(dataExt$WGTVICCY), and sum(dataExt$SERIES_WEIGHT). What does each number represent?
Calculate the percentage increase from WGTVICCY to SERIES_WEIGHT. This is the effect of accounting for series victimizations on the estimated total.
5 Tabulating victimizations
First, we need to be clear about what we are counting. BJS reports on victimizations and incidents. For personal crimes, victimizations count the number of people victimized. For household property crimes, the affected household is treated as the victim. Incidents count criminal events, and a single incident can involve multiple victims. BJS reports largely focus on criminal victimizations.
We can start by just asking the NCVS data how many criminal victimizations there were in 2022. We compute that as the sum of all the weights.
sum(dataExt$SERIES_WEIGHT)
[1] 20121320
This means that the NCVS estimates that there were 20,121,320 criminal victimizations in the United States in 2022.
Let’s take a closer look at what kinds of victimization occurred. Note that this code breaks the dataset into groups based on the reported crime type, V4529, and computes the total weight associated with each of those crime categories.
# A tibble: 33 × 2
V4529 total
<fct> <dbl>
1 (01) Completed rape 127522.
2 (02) Attempted rape 67330.
3 (03) Sex aslt w s aslt 27038.
4 (04) Sex aslt w m aslt 7511.
5 (05) Rob w inj s aslt 87026.
6 (06) Rob w inj m aslt 88620.
7 (07) Rob wo injury 216589.
8 (08) At rob inj s asl 25197.
9 (09) At rob inj m asl 47896.
10 (10) At rob w aslt 119279.
11 (11) Ag aslt w injury 449842.
12 (12) At ag aslt w wea 397249.
13 (13) Thr aslt w weap 637952.
14 (14) Simp aslt w inj 578068.
15 (15) Sex aslt wo inj 118078.
16 (16) Unw sex wo force 52425.
17 (17) Asl wo weap, wo inj 1295757.
18 (18) Verbal thr rape 41862.
19 (19) Ver thr sex aslt 15501.
20 (20) Verbal thr aslt 1978623.
21 (21) Purse snatching 35375.
22 (23) Pocket picking 124503.
23 (31) Burg, force ent 549203.
24 (32) Burg, ent wo for 1074214.
25 (33) Att force entry 312530.
26 (40) Motor veh theft 518797.
27 (41) At mtr veh theft 193058.
28 (54) Theft < $10 623035.
29 (55) Theft $10-$49 1735619.
30 (56) Theft $50-$249 2968819.
31 (57) Theft $250+ 3057945.
32 (58) Theft value NA 1799273.
33 (59) Attempted theft 749585.
The first 20 crime types listed are violent crimes, codes 21 through 23 are personal larceny (like pickpocketing… no violence or breaking into a home), and the remainder are household property crimes. For household property crimes, the NCVS treats the household, rather than an individual respondent, as the victim. Let’s extract the two-digit code between the parentheses so that we can classify the crime types.
V4529 crimeCode crimeType
1 (41) At mtr veh theft 41 property
2 (59) Attempted theft 59 property
3 (58) Theft value NA 58 property
4 (57) Theft $250+ 57 property
5 (55) Theft $10-$49 55 property
6 (07) Rob wo injury 7 violent
That all looks correct, so now I can move on to the tabulation.
a <- dataExt |>group_by(crimeType) |>summarize(estTotal =sum(SERIES_WEIGHT))a
# A tibble: 3 × 2
crimeType estTotal
<chr> <dbl>
1 personal larceny 159878.
2 property 13582078.
3 violent 6379364.
In our calendar-year 2022 dataset, there were an estimated 6,379,364 violent victimizations, 159,878 personal larcenies, and 13,582,078 household property victimizations.
We can summarize other categories, like car thefts, attempted and completed.
dataExt |>filter(V4529 %in%c("(40) Motor veh theft","(41) At mtr veh theft")) |>summarize(sum(SERIES_WEIGHT))
sum(SERIES_WEIGHT)
1 711855.4
Measuring sexual assault has been complicated by numerous, sometimes major, changes (improvements, more precisely) in the definitions and data collection methods (e.g., question wording). The FBI’s Uniform Crime Reporting Program made a major change to the definition of rape in 2013. The NCVS began phasing in its most recent instrument change in 2024. See Fisher and Gross (2025) for an extended discussion and timeline of the changes.
Here is the NCVS estimate of the number of rapes (attempted and completed) for 2022.
Official NCVS reports combine rape and sexual assault. There are a lot of crime categories that describe these victimizations.
unique(dataExt$V4529)
[1] (41) At mtr veh theft (59) Attempted theft (58) Theft value NA
[4] (57) Theft $250+ (55) Theft $10-$49 (07) Rob wo injury
[7] (13) Thr aslt w weap (17) Asl wo weap, wo inj (20) Verbal thr aslt
[10] (32) Burg, ent wo for (56) Theft $50-$249 (14) Simp aslt w inj
[13] (54) Theft < $10 (31) Burg, force ent (19) Ver thr sex aslt
[16] (23) Pocket picking (10) At rob w aslt (11) Ag aslt w injury
[19] (40) Motor veh theft (33) Att force entry (12) At ag aslt w wea
[22] (04) Sex aslt w m aslt (21) Purse snatching (03) Sex aslt w s aslt
[25] (16) Unw sex wo force (09) At rob inj m asl (02) Attempted rape
[28] (06) Rob w inj m aslt (15) Sex aslt wo inj (18) Verbal thr rape
[31] (01) Completed rape (08) At rob inj s asl (05) Rob w inj s aslt
34 Levels: (01) Completed rape (02) Attempted rape ... (59) Attempted theft
Let’s count any that have the word “rape” and any that have the word “sex” (sometimes capitalized). Here are the ones that BJS counts in this category.
V4529
1 (19) Ver thr sex aslt
2 (04) Sex aslt w m aslt
3 (03) Sex aslt w s aslt
4 (16) Unw sex wo force
5 (02) Attempted rape
6 (15) Sex aslt wo inj
7 (18) Verbal thr rape
8 (01) Completed rape
The estimated number of all sexual assaults in 2022 in the United States is
Since 2020, we have not had national police-reported crime estimates. The FBI transitioned away from the traditional Summary Reporting System (SRS) series in 2021, and its replacement, NIBRS, has had low participation rates with minimal reporting from California, New York, Florida, and Pennsylvania.
The NCVS’s value lies in its inclusion of victimizations that were never reported to police.
NoteExercises
Using crimeType, calculate the weighted percentage of all victimizations in each of the three categories: violent crime, personal larceny, and household property crime
Estimate the number and weighted percentage of motor vehicle thefts that were attempts rather than completed thefts
6 Calculating victimization by demographics
In the remainder of these notes, we will examine relationships between personal victimization and respondents’ features, like age (V3014), marital status (V3015), and sex (V3018). To make the code clearer, let’s give these variables more intelligible names.
Perhaps we are interested in which personal crimes disproportionately affect men and which disproportionately affect women. Household property crimes are attributed to the household rather than to an individual victim, so we will exclude them from these demographic comparisons. Start by tabulating personal crime type by sex.
`summarise()` has regrouped the output.
ℹ Summaries were computed grouped by V4529 and sex.
ℹ Output is grouped by V4529.
ℹ Use `summarise(.groups = "drop_last")` to silence this message.
ℹ Use `summarise(.by = c(V4529, sex))` for per-operation grouping
(`?dplyr::dplyr_by`) instead.
# A tibble: 43 × 3
# Groups: V4529 [22]
V4529 sex count
<fct> <fct> <dbl>
1 (01) Completed rape (1) Male 18080.
2 (01) Completed rape (2) Female 109442.
3 (02) Attempted rape (1) Male 2190.
4 (02) Attempted rape (2) Female 65140.
5 (03) Sex aslt w s aslt (2) Female 27038.
6 (04) Sex aslt w m aslt (1) Male 677.
7 (04) Sex aslt w m aslt (2) Female 6834.
8 (05) Rob w inj s aslt (1) Male 52000.
9 (05) Rob w inj s aslt (2) Female 35026.
10 (06) Rob w inj m aslt (1) Male 16581.
11 (06) Rob w inj m aslt (2) Female 72039.
12 (07) Rob wo injury (1) Male 102379.
13 (07) Rob wo injury (2) Female 114209.
14 (08) At rob inj s asl (1) Male 16131.
15 (08) At rob inj s asl (2) Female 9065.
16 (09) At rob inj m asl (1) Male 31641.
17 (09) At rob inj m asl (2) Female 16255.
18 (10) At rob w aslt (1) Male 57154.
19 (10) At rob w aslt (2) Female 62125.
20 (11) Ag aslt w injury (1) Male 195301.
21 (11) Ag aslt w injury (2) Female 254541.
22 (12) At ag aslt w wea (1) Male 189557.
23 (12) At ag aslt w wea (2) Female 207692.
24 (13) Thr aslt w weap (1) Male 402951.
25 (13) Thr aslt w weap (2) Female 235001.
26 (14) Simp aslt w inj (1) Male 214975.
27 (14) Simp aslt w inj (2) Female 363093.
28 (15) Sex aslt wo inj (1) Male 22433.
29 (15) Sex aslt wo inj (2) Female 95645.
30 (16) Unw sex wo force (1) Male 7980.
31 (16) Unw sex wo force (2) Female 44446.
32 (17) Asl wo weap, wo inj (1) Male 648373.
33 (17) Asl wo weap, wo inj (2) Female 647384.
34 (18) Verbal thr rape (1) Male 15134.
35 (18) Verbal thr rape (2) Female 26727.
36 (19) Ver thr sex aslt (1) Male 5480.
37 (19) Ver thr sex aslt (2) Female 10021.
38 (20) Verbal thr aslt (1) Male 1021068.
39 (20) Verbal thr aslt (2) Female 957555.
40 (21) Purse snatching (1) Male 1947.
41 (21) Purse snatching (2) Female 33428.
42 (23) Pocket picking (1) Male 92254.
43 (23) Pocket picking (2) Female 32249.
R produces a long narrow table. This format is sometimes useful, particularly when merging data frames. However, in this case having a table with counts for men and women side-by-side would be easier to absorb. pivot_wider() will swing the sex column into two side-by-side columns.
dataExt |>filter(crimeCode <=23) |>group_by(V4529, sex) |>summarize(count=sum(SERIES_WEIGHT)) |>pivot_wider(names_from=sex,values_from=count,values_fill =0) |># fill in NAs with 0print(n=Inf)
`summarise()` has regrouped the output.
ℹ Summaries were computed grouped by V4529 and sex.
ℹ Output is grouped by V4529.
ℹ Use `summarise(.groups = "drop_last")` to silence this message.
ℹ Use `summarise(.by = c(V4529, sex))` for per-operation grouping
(`?dplyr::dplyr_by`) instead.
# A tibble: 22 × 3
# Groups: V4529 [22]
V4529 `(1) Male` `(2) Female`
<fct> <dbl> <dbl>
1 (01) Completed rape 18080. 109442.
2 (02) Attempted rape 2190. 65140.
3 (03) Sex aslt w s aslt 0 27038.
4 (04) Sex aslt w m aslt 677. 6834.
5 (05) Rob w inj s aslt 52000. 35026.
6 (06) Rob w inj m aslt 16581. 72039.
7 (07) Rob wo injury 102379. 114209.
8 (08) At rob inj s asl 16131. 9065.
9 (09) At rob inj m asl 31641. 16255.
10 (10) At rob w aslt 57154. 62125.
11 (11) Ag aslt w injury 195301. 254541.
12 (12) At ag aslt w wea 189557. 207692.
13 (13) Thr aslt w weap 402951. 235001.
14 (14) Simp aslt w inj 214975. 363093.
15 (15) Sex aslt wo inj 22433. 95645.
16 (16) Unw sex wo force 7980. 44446.
17 (17) Asl wo weap, wo inj 648373. 647384.
18 (18) Verbal thr rape 15134. 26727.
19 (19) Ver thr sex aslt 5480. 10021.
20 (20) Verbal thr aslt 1021068. 957555.
21 (21) Purse snatching 1947. 33428.
22 (23) Pocket picking 92254. 32249.
Lastly, let’s normalize the columns so that they add up to 100%, giving us the distribution of crime types within each sex.
dataExt |>filter(crimeCode <=23) |>group_by(V4529, sex) |>summarize(count=sum(SERIES_WEIGHT)) |>ungroup() |># without this, percentages are computed within crime typepivot_wider(names_from = sex,values_from = count,values_fill =0) |>rename(male=`(1) Male`, female=`(2) Female`) |>mutate(male =100*male/sum(male),female=100*female/sum(female),ratio=female/male) |>arrange(desc(ratio)) |>print(n=Inf)
`summarise()` has regrouped the output.
ℹ Summaries were computed grouped by V4529 and sex.
ℹ Output is grouped by V4529.
ℹ Use `summarise(.groups = "drop_last")` to silence this message.
ℹ Use `summarise(.by = c(V4529, sex))` for per-operation grouping
(`?dplyr::dplyr_by`) instead.
# A tibble: 22 × 4
V4529 male female ratio
<fct> <dbl> <dbl> <dbl>
1 (03) Sex aslt w s aslt 0 0.789 Inf
2 (02) Attempted rape 0.0703 1.90 27.0
3 (21) Purse snatching 0.0625 0.976 15.6
4 (04) Sex aslt w m aslt 0.0217 0.200 9.18
5 (01) Completed rape 0.581 3.20 5.50
6 (16) Unw sex wo force 0.256 1.30 5.06
7 (06) Rob w inj m aslt 0.532 2.10 3.95
8 (15) Sex aslt wo inj 0.720 2.79 3.88
9 (19) Ver thr sex aslt 0.176 0.293 1.66
10 (18) Verbal thr rape 0.486 0.780 1.61
11 (14) Simp aslt w inj 6.90 10.6 1.54
12 (11) Ag aslt w injury 6.27 7.43 1.19
13 (07) Rob wo injury 3.29 3.33 1.01
14 (12) At ag aslt w wea 6.09 6.06 0.996
15 (10) At rob w aslt 1.84 1.81 0.988
16 (17) Asl wo weap, wo inj 20.8 18.9 0.908
17 (20) Verbal thr aslt 32.8 28.0 0.853
18 (05) Rob w inj s aslt 1.67 1.02 0.612
19 (13) Thr aslt w weap 12.9 6.86 0.530
20 (08) At rob inj s asl 0.518 0.265 0.511
21 (09) At rob inj m asl 1.02 0.475 0.467
22 (23) Pocket picking 2.96 0.942 0.318
Sexual assaults disproportionately affect women, while pocket picking and attempted robbery involving assaults disproportionately affect men.
The sequence group_by(), summarize(), ungroup() is so common that there is an alternative way to do the same calculation more compactly with .by in summarize(). A frequent R error is to use group_by(), then forget that the data is still grouped, and continue to do calculations unaware that they are occurring only within groups. The .by argument also helps avoid this error.
# can reduce the group_by, summarize, ungroup with .bydataExt |>filter(crimeCode <=23) |>summarize(count=sum(SERIES_WEIGHT),.by =c(V4529, sex)) |># eliminates group/ungrouppivot_wider(names_from = sex,values_from = count,values_fill =0) |>rename(male=`(1) Male`, female=`(2) Female`) |>mutate(male =100*male/sum(male),female=100*female/sum(female),ratio=female/male) |>arrange(desc(ratio)) |>print(n=Inf)
# A tibble: 22 × 4
V4529 male female ratio
<fct> <dbl> <dbl> <dbl>
1 (03) Sex aslt w s aslt 0 0.789 Inf
2 (02) Attempted rape 0.0703 1.90 27.0
3 (21) Purse snatching 0.0625 0.976 15.6
4 (04) Sex aslt w m aslt 0.0217 0.200 9.18
5 (01) Completed rape 0.581 3.20 5.50
6 (16) Unw sex wo force 0.256 1.30 5.06
7 (06) Rob w inj m aslt 0.532 2.10 3.95
8 (15) Sex aslt wo inj 0.720 2.79 3.88
9 (19) Ver thr sex aslt 0.176 0.293 1.66
10 (18) Verbal thr rape 0.486 0.780 1.61
11 (14) Simp aslt w inj 6.90 10.6 1.54
12 (11) Ag aslt w injury 6.27 7.43 1.19
13 (07) Rob wo injury 3.29 3.33 1.01
14 (12) At ag aslt w wea 6.09 6.06 0.996
15 (10) At rob w aslt 1.84 1.81 0.988
16 (17) Asl wo weap, wo inj 20.8 18.9 0.908
17 (20) Verbal thr aslt 32.8 28.0 0.853
18 (05) Rob w inj s aslt 1.67 1.02 0.612
19 (13) Thr aslt w weap 12.9 6.86 0.530
20 (08) At rob inj s asl 0.518 0.265 0.511
21 (09) At rob inj m asl 1.02 0.475 0.467
22 (23) Pocket picking 2.96 0.942 0.318
We can do a similar calculation by age. First, let’s discretize age into some fixed age bins. Then, we can repeat the same calculation to learn about victimization differences by age. I have sorted the results by the 18-24 age category, but you can change it to your age category if you wish.
# can reduce the group_by, summarize, ungroup with .bydataExt |>filter(crimeCode <=23) |>mutate(ageGroup =cut(age, breaks =c(0, 17, 24, 34, 49, 64, Inf),labels =c("12-17","18-24","25-34","35-49","50-64","65+"))) |>summarize(count=sum(SERIES_WEIGHT),.by =c(V4529, ageGroup)) |>pivot_wider(names_from = ageGroup,values_from = count,values_fill =0,names_sort =TRUE) |># keep age groups ordered# apply the same function to every column, except V4529mutate(across(-V4529, function(x) 100*x/sum(x))) |>arrange(desc(`18-24`)) |># you can change to your age groupprint(n=Inf)
# A tibble: 22 × 7
V4529 `12-17` `18-24` `25-34` `35-49` `50-64` `65+`
<fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 (20) Verbal thr aslt 20.1 23.3 31.6 29.9 37.7 35.6
2 (17) Asl wo weap, wo inj 33.2 14.9 19.6 24.2 13.2 18.3
3 (13) Thr aslt w weap 5.12 11.3 10.4 10.8 10.3 6.71
4 (12) At ag aslt w wea 6.91 8.45 4.29 6.61 5.89 4.12
5 (11) Ag aslt w injury 4.79 8.35 7.15 7.05 7.94 2.89
6 (14) Simp aslt w inj 12.9 8.13 10.1 7.28 8.60 7.11
7 (15) Sex aslt wo inj 3.24 4.18 1.35 0.944 1.39 0
8 (01) Completed rape 0.284 3.80 3.23 1.78 0.206 1.52
9 (07) Rob wo injury 2.50 3.24 3.09 2.65 3.66 5.84
10 (06) Rob w inj m aslt 1.34 2.99 2.74 0.0720 0.152 0.877
11 (02) Attempted rape 0.338 2.61 0.352 1.30 0.729 0.489
12 (21) Purse snatching 0 2.47 0 0 0.405 0.563
13 (10) At rob w aslt 0.840 1.53 1.59 1.58 2.56 3.04
14 (23) Pocket picking 2.34 1.03 1.37 1.69 1.85 5.11
15 (08) At rob inj s asl 1.38 0.943 0.255 0.155 0 0
16 (16) Unw sex wo force 3.06 0.919 0.375 0 0.837 1.09
17 (18) Verbal thr rape 0.181 0.719 0.491 0.640 1.18 0.143
18 (05) Rob w inj s aslt 0 0.443 1.24 0.891 2.88 2.34
19 (03) Sex aslt w s aslt 0 0.408 0.200 0 0 3.44
20 (09) At rob inj m asl 0.512 0.315 0.374 1.96 0.312 0.459
21 (19) Ver thr sex aslt 0.414 0 0.360 0.317 0.0569 0.382
22 (04) Sex aslt w m aslt 0.590 0 0 0.145 0.117 0
NoteExercise
Repeat the demographic analysis using marital status. For each marital-status group, calculate the weighted percentage of personal victimizations in every crime category. Which crime types make up a larger percentage among divorced respondents than among married respondents?
Since we have made many changes to the dataset, I find it useful to save the final version. This way I can simply load() the data again later and know that it already has all the edits and changes that I have made.
Compare nrow(dataExt), sum(dataExt$WGTVICCY), and sum(dataExt$SERIES_WEIGHT). What does each number represent?
nrow(dataExt)
[1] 9539
sum(dataExt$WGTVICCY)
[1] 18201324
sum(dataExt$SERIES_WEIGHT)
[1] 20121320
nrow(dataExt) is the unweighted number of records in our extract. sum(dataExt$WGTVICCY) is the estimated number of victimizations when every series record is counted once. sum(dataExt$SERIES_WEIGHT) is the estimated number of victimizations after counting up to 10 occurrences of each series crime.
Calculate the percentage increase from WGTVICCY to SERIES_WEIGHT. This is the effect of accounting for series victimizations on the estimated total.
Using crimeType, calculate the weighted percentage of all victimizations in each of the three categories: violent crime, personal larceny, and household property crime
Estimate the number and weighted percentage of motor vehicle thefts that were attempts rather than completed thefts
dataExt |>filter(V4529 %in%c("(40) Motor veh theft","(41) At mtr veh theft")) |>summarize(count=sum(SERIES_WEIGHT), .by=V4529) |>mutate(percent=100*count/sum(count))
V4529 count percent
1 (41) At mtr veh theft 193058.2 27.12043
2 (40) Motor veh theft 518797.1 72.87957
Repeat the demographic analysis using marital status. For each marital-status group, calculate the weighted percentage of personal victimizations in every crime category. Which crime types make up a larger percentage among divorced respondents than among married respondents?
Fisher, Bonnie S., and Rachel L. Gross. 2025. “The Evolution of the Measurement of Rape and Sexual Assault over 50 Years: Milestones, Definitions, Operationalizations, and Classifications.”Journal of Contemporary Criminal Justice 41 (1): 166–95. https://doi.org/10.1177/10439862241290352.