ONET CPS Crosswalk


I am trying to find/create a crosswalk from ONET to CPS IPUMS for 1979-2015. CPS IPUMS provides a variable (OCC1990) with consistent occupation coding scheme based on the 1990 coding scheme. Ideally, I would like to find a crosswalk that translates ONET SOC codes to the codes of this consistent CPS IPUMS variable.

Do you by any chance know if such a crosswalk exists? If not, do you have a suggestion how I could map O*NET SOC codes to 1979-2015 CPS IPUMS?

I tried to create a crosswalk from ONET to CPS IPUMS by using a crosswalk from ONET SOC codes to SOC 2018 codes, SOC 2018 codes to SOC 2010 codes, and SOC 2010 codes to Census 2010 codes (these codes are used in CPS for 2011-2015). I even tried going back to Census 2002 codes (these codes are used in CPS for 2003-2010). However, there are fewer occupation codes for 2011-2015 (or 2003-2015) than for 1979-2015. So, I cannot map all occupations from CPS to O*NET.

Any help is greatly appreciated! Thanks in advance!

My understanding is that you’d like to assign a modern O*Net code to data from earlier years, in a way that is consistent over time. So you’d essentially want to create a version of OCC1990 or OCC2010, except instead of the codes being based on the 2010 census occupation codes, they are based on O*Net codes. There’s no existing crosswalk that does this. I think probably the simplest thing to do is try to piggyback on the OCC2010 variable. First choose a single O*Net code to represent a given OCC2010 code in modern samples. You can get a head start on this process using the IPUMS USA variable OCCSOC (discussed below). However the OCCSOC crosswalk is to OCC, not OCC2010, so you’d need to make some manual adjustments for cases where OCC codes don’t exactly correspond to the OCC2010 codes. Once you’ve made a correspondence between OCCSOC and OCC2010, you can then assign the OCCSOC value to each observation back to 1979, based on the OCC2010 code. I hope that makes sense.

About assigning O*Net codes to census codes:

Census occupation codes (at least since 2000) are based off of the SOC system. A census code either corresponds exactly to a single 6-digit SOC code, or to a collection of SOC codes. O*Net is also based on the SOC system, but instead of grouping codes, it splits some SOC codes into even more detailed codes. My understanding is that you’d like to recode the IPUMS CPS occupation codes to the O*Net system. The problem is that O*Net has substantially more detail than CPS. The Census Bureau has tackled a similar issue in creating the variable OCCSOC, which codes census occupation codes into SOC codes. However, when a given census code corresponds to multiple SOC codes, the OCCSOC code is an aggregated code. You can see the correspondences here. For example, in the 2013-2017 ACS, the code 10 means “chief executives and legislators,” which has an OCCSOC code of 1110XX. This is not an actual SOC code, but groups together three SOC codes, 111011, 111021, 111031. (see the SOC 2010 codes here). If you wanted to assign an O*Net code, you’d additionally be grouping sub-codes into that OCCSOC code, such as 111011.03 (chief sustainability officers). However the CPS won’t tell you if a given individual is a legislator, a CEO, or a chief sustainability officer. So assigning an O*Net code will give no more information than an OCCSOC code.