Reshapes LASA data between wide format – one row per respondent, with
a separate column for each variable at each wave (boak, coak,
doak, ...), the way LASA's Z files (e.g. LASAZOA1.SAV) store
information that spans waves – and long format: one row per
respondent per wave, one column per variable (oak), and a "Wave"
column saying which wave each row belongs to, the way read_lasa_sav()
returns a single wave file. Works on a file read by read_lasa_sav()
(read_lasa_sav(format_as_long = TRUE) calls it for you), on several
LASA files merged together, and on any data frame with a respnr
column.
Arguments
- data
A data frame or tibble with one respondent identifier column named
respnr(in any capitalization), for example the result ofread_lasa_sav(), or several LASA files merged together. Long data also have a"Wave"column (in any capitalization) of LASA wave codes.- format
"long"(the default) or"wide": the format to transformdatainto.- prefix
"Wave"(the default) or"Time": what the names of wave-specific columns start with in wide format. Only used whenformat = "wide"; see Details.
Value
data in the requested format, as a data frame (or a tibble if
data is one), keeping data's provenance attributes. Its
"LASA_wave" attribute is updated to the data's single wave if there
is only one, removed from long data that span several waves, and
"Z" for wide data that span several waves (as for a Z file). Long
data that span several waves can't be relabelled with
apply_lasa_labels(), which labels one file and wave at a time:
label each file before transforming it.
Details
Long format has one row per respondent per wave, with a "Wave"
column (the LASA wave code, e.g. "B", "2B", "MB") and a "Time"
column right after respnr. Each wave-specific variable becomes one
column named after its wave-stripped (canonical) name, so boak, coak,
... become oak. A respondent gets a row for each wave at which at least
one of the wave-specific columns has a value for them – anything but
NA or blank text (which is how SPSS stores missing text), so a
missing-value code kept as a value (read with
read_lasa_sav(keep_user_na = TRUE)) counts too. Respondents of a
later cohort therefore only get rows for the waves before they joined
LASA where the data hold such a code for them, as LASA's Z files do
("no observation birth cohorts 1938-1947"). A respondent without any
value at any wave keeps a row for every wave, so nobody disappears.
Rows are sorted by respondent (in order of first appearance) and wave,
except in long data without wide columns, which keep their order.
Time counts the waves since the respondent's baseline, the wave at which their cohort joined LASA, which is Time 0. A cohort takes part in every later wave except the other cohorts' baselines:
first cohort: B = 0, C = 1, D = 2, E = 3, F = 4, G = 5, H = 6, I = 7, J = 8, K = 9, L = 10;
second cohort: 2B = 0, F = 1, G = 2, H = 3, I = 4, J = 5, K = 6, L = 7;
third cohort and migrant cohort: 3B or MB = 0, I = 1, J = 2, K = 3, L = 4;
fourth cohort: 4B = 0, L = 1.
Wave A, the LSN pilot study a few months before wave B, isn't part of any
cohort's waves: its rows keep "Wave" "A" and have no Time (NA).
Time counts waves, not years, and it isn't LASA's own wave numbering,
which LASAZ008.SAV uses (t2_dat is wave B there); for time itself,
use the interview dates or ages in LASAZ008.SAV.
A row's Time depends on the respondent's cohort, which the data show by:
a value (other than
NA, blank text, or a missing-value code) at the respondent's baseline or at a wave only their cohort takes part in (B to E for the first cohort);a single LASA file of such a wave, whose respondents all belong to its cohort, whatever their values (the data's
"LASA_file_code"and"LASA_wave"attributes say which file; not a Z file, whose rows may hold codes for waves before a cohort joined): in long data all of whose rows are of that wave, any row, unless it holds nothing but values a guess put at its wave (see Names of several waves); in wide data (the file read with LASA's own names,standardize = FALSEinread_lasa_sav(), or transformed to wide format), every respondent, as long as all columns are the file's (those its label report lists, and the names wide format gives columns of its wave) – once other data are joined on, every respondent with a value in one of the file's columns (one the join added has none), also when the file in wide data was joined onto long data, keeping its attributes (asdplyr's joins do with it first);LASA's
cohortcolumn, asLASAZ002.SAVand Time-prefixed wide data (see Wide format) have it:"cohort 1 (1992)"– also written"Cohort 1"or"cohort 1 (1992/1993)"– or its code 1 is the first cohort, whose baseline is B; cohort 2's is 2B, cohort 3's 3B, cohort 4's 4B, and the"migrant cohort"'s MB;a
"Time"column already in long data;the respondent number: LASA numbers its respondents with five digits, the first of which is 1, 2, or 3 in the first cohort, 4, 5, or 6 in the second cohort, and 7, 8, or 9 in the third. A 1 also numbers the LSN pilot study's respondents, so it only says the first cohort of a respondent the data show at a wave other than A, by a value there (rows that hold nothing but missing-value codes don't count). The fourth and the migrant cohort's numbers aren't known yet: if they have five digits too, they say one of the first three cohorts until the rest of the data show their own (their baseline file, say, or a
cohortcolumn). A number of any other form (the longer numbers the fourth cohort may have, or the small numbers of the examples below) says nothing. Where the rest of the data show another cohort than a respondent's number, they decide, with a warning in long and Time-prefixed wide format, which show the cohort – also over a"Time"column that follows the number, asread_lasa_sav()and long format give it where the data don't show the cohort: at waves several cohorts share, and on rows holding nothing but missing-value codes (a Time at wave B is the first cohort's). Such a Time gives way also where a file of a wave of one cohort gave it, which stacked files no longer show.
A missing-value code is what read_lasa_sav() turns into NA unless
keep_user_na = TRUE: an SPSS user-missing value; in a variable the
label database documents, any negative code, documented or not, except
in a variable whose values can be negative at that wave (such as the
speech-reception thresholds msrttn), where only its documented codes
are; and in any column, a negative code with a value label – also as
the text or factor level read_lasa_sav() gives it (its label, or its own
number). Values show the cohort in the wave-specific variables the label
database documents (and long columns transform_lasa_data() made from
wide columns); in long data without any, in the columns whose values
differ between a respondent's rows (a variable computed per wave, say;
an NA counts as a value of its own), or else in all columns but the
documented stable variables; and in long data without such columns,
every row shows its wave. The waves from F on, which cohorts share,
don't show the cohort: the rows of a respondent seen only at those waves
get no Time, with a message, unless their respondent number or another
of the sources above shows it (or every cohort the data leave open gives
their wave the same Time). Data showing waves of several cohorts for one
respondent give that respondent no Time, with a warning.
A "Time" column already in long data – also the Time.x/Time.y
columns merge() makes of two, and the further copies merging more data
sets gives (Time.x.x, or several of the same name) – must give each
row a Time that the respondent's cohort, as far as the rest of the data
show it, gives its wave, and copies must agree with each other, except
that a copy following the respondent number gives way to one that
doesn't (that of a file of a wave several cohorts share read on its
own, next to that of data that showed another cohort, say); it is
replaced by the recomputed one.
A cohort column (in any capitalization) is LASA's when its values,
factor levels, or value labels name cohorts the way above, or when it
holds nothing but their codes (and missing values): LASA's codes 1 to 4,
and 5 for the migrant cohort, as Time-prefixed wide data code it, as
numbers, or as text or factor levels ("4", the way read_lasa_sav()
reads a code the label database doesn't document) – unless value labels
say they are something else (birth cohorts, say; labels of negative
missing-value codes aside). In a column whose value labels name cohorts,
a code without a value label names its cohort too, as does one labelled
with its own number (the level "4" in a .sav file). Any other
cohort column is an ordinary column. LASA's cohort column must give each
respondent one cohort, which the waves the data show must fit; values
that name no cohort (a missing-value code) say nothing. In long format,
it stays as it is; coded as Time-prefixed wide data have it (as
read_lasa_sav() reads LASAZ002.SAV's), it gets back the labels
merge() and row subsetting drop. Several columns named cohort – the
cohort.x/cohort.y columns of data sets with a cohort column merged
by respnr (LASAZ002.SAV, Time-prefixed wide data), the further
copies merging more of them gives (cohort.x.x, or several of the same
name), and columns whose names differ in capitalization only
(LASAZ002.SAV's COHORT as haven::read_sav() reads it, next to
Time-prefixed wide data's cohort) – are combined into one cohort,
coded as Time-prefixed wide data have it, and must agree. A copy that
names no cohort is another data set's own column, and stays as it is; a
column named cohort that names none, next to one that does, is an
error.
Stable variables – columns that hold for every wave, such as sex or
year of birth (byear) in LASAZ004.SAV – keep one column and are
repeated on each of the respondent's rows: in long data, a stable
variable the label database documents is filled in on the respondent's
rows where it is missing (rows other files' columns added, or rows of
other waves merged in by respnr and "Wave") from their other rows,
as long as those agree. A file without wave-specific columns, such as
LASAZ004.SAV or the migrant cohort's LASMB004.SAV, has no wave
dimension: it stays one row per respondent, without "Wave" and
"Time" columns, with a message.
Which columns are wave-specific is decided per column: a column made
wide by transform_lasa_data() itself is recognized by its name, or by
attributes it carries where its name doesn't say enough (see Wide
format); any other column is wave-specific when lasa_label_db()
documents its name as a wave-specific variable – which covers LASA's
irregular names too, such as t2_dat (t_dat, wave B), b_dm (dm),
b2oak (oak, wave 2B), or totalalpha, which LASA's wave H file uses
without a wave prefix, and a column read_lasa_sav() matched to such a
name by fuzzy matching or name_corrections – or, for data that aren't
long yet (no "Wave" column, or one holding nothing but the "Z"
placeholder read_lasa_sav() gives a Z file and the missing values
merging with that file gives – only missing values, too, in data with
one row per respondent), when its name is a wave prefix followed by a
variable the label database documents for that wave (the names wide
format uses, see below), by any wave-specific variable it documents if
the wave is 4B or L, which it doesn't document yet (lhhnch), or by a
variable LASA's wave files name without a wave prefix if the wave isn't
A (kseh_reden). All other columns are
treated as stable, including columns the label database doesn't know. A
warning names columns kept stable that look like wave-specific
variables: names a merge suffixed with .x/.y, and, in wide data,
variables read with their wave stripped from their name.
In long data, a column named after a variable (its long-format name) is
that variable's long column, whose values stay at their rows' waves.
So is a column of a wave-specific name whose values are all on rows of
waves that name stands for: the waves the label database documents it
at, and the wave of the LASA file the data are (as far as the data's
label report lists the column) – also where the label database doesn't
document the name at that wave, as for the files of waves 4B and L,
which it doesn't document yet – and, for a name LASA's wave files use
without a wave prefix (drinking), those undocumented waves, any wave
once its values differ between a respondent's rows, and, in the data of
that name's LASA file (as far as the data's label report lists the
column; stacked files keep the first one's), the waves lasa_topics()
lists the file at that the label database doesn't document of it yet
(wave K for file 045's seh_reden), unless the file's wave-prefixed
columns are wide there (a wide file joined onto other long data). In the
data of a LASA file of wave L, a column the file's label report lists
named l followed by a wave-specific variable (lhhnch) is that variable's
long column too, so wave L's files become long as other waves' do. Wave
I's immse01 to immse23 are also the long names of the migrant
cohort's bimmse01 to bimmse23: such a column is the migrant cohort's
long column when its values are on rows of wave MB (or its
canonical_name attribute says so), and wave I's column otherwise.
Names of several waves. LASA's wave files name the baseline of every
cohort (B, 2B, 3B, MB, and 4B) with the same b prefix, so a name such
as blphya01 may belong to any of them, and a few other names stand for
several waves too (bqvalu16 for waves 3B and J, xcancer1 for waves B
and C). Each respondent's value in such a column goes to the wave the
data show for that respondent: in long data, a value already on a row of
one of those waves stays there; otherwise, the respondent's cohort, as
far as the data (or else the respondent number) show it (the first
cohort has no wave 3B, so its respondents' bqvalu16 is wave J's), and
then the file the column came from (the data's "LASA_file_code" and
"LASA_wave" attributes, as far as the data's label report lists the
column, since a merge keeps at most the first file's attributes). If
nothing says, the value goes, with a message naming the column, to the
first of these waves the respondent's cohort may take part in: the wave
the column's other respondents were placed at by their cohort, the wave
of the data's "LASA_wave" attribute, and the column's waves in
calendar order (and
for a name LASA's wave files use without a wave prefix, drinking, if
the respondent's cohort takes part in none of those: waves 4B and L,
which the label database doesn't document yet). Such a guess doesn't
count as showing the respondent's cohort, so it gives none of their
rows a Time unless something else, such as their respondent number,
shows the cohort (which may leave several of the column's waves open:
the third cohort takes part in both of bqvalu16's) – also when the
result is transformed again: the long
column remembers which of its values were placed by a guess, and wide
format gives those values one column, also when the guesses put them at
several waves, under a name that doesn't say the wave (its original
name, or else LASA's own, such as blphya01), so transforming that back
guesses again, with the message. The long column keeps that memory in
its attributes, which rbind(), merge(), dplyr::bind_rows(),
subsetting or sorting the rows of a data frame (rather than a tibble),
and writing the data to a .sav file can drop: after that, those values
count as showing the cohort of the wave they were put at. To avoid
guesses, transform each LASA file to long format before combining files
(with format_as_long = TRUE in read_lasa_sav()).
One name stands for two variables at one wave: bmmsesc1 is file 221's
mmsesc and file 421's mmsesc1 at wave MB. The data's file (or the
column's canonical_name attribute) says which; otherwise it is taken
as the variable the name stands for at its other waves (mmsesc1), with
a message.
Merged files. data may be several LASA files merged together, in
any of three shapes:
long (the most reliable): files read with
format_as_long = TRUE, which gives each file's rows their Time while the file still shows their cohort (in a baseline file, also rows holding nothing but missing-value codes), stacked per file code withdplyr::bind_rows()(orrbind(), if the files have the same columns) and merged byrespnrand"Wave"(withall = TRUE, to keep the rows of respondents missing from some files); theTime.xandTime.ycolumns that merge makes become one"Time"again, now also for the rows of files that didn't show the respondent's cohort on their own. Stacking and merging drop the columns' labels (or keep one file's for all rows), whichtransform_lasa_data()gives back (see Labels). A file without wave-specific columns (LASAZ004.SAV,LASMB004.SAV) read withformat_as_long = TRUEhas no"Wave"column: merge it byrespnralone;wide, e.g.
LASAB046.SAV,LASAC046.SAV,LASAB030.SAV, ... read withstandardize = FALSEand merged byrespnr(withall = TRUE), or a Z file merged withLASAZ004.SAV.merge()drops the files' attributes (dplyr's joins keep the first data set's), so the values inbcolumns of a respondent the data show nowhere else (one who dropped out after wave B, say) go to the baseline their respondent number says, or else are placed by a guess (see Names of several waves), which gives them no Time. So merge the baseline files of the migrant and the fourth cohort (LASMB046.SAV,LAS4B046.SAV), whose respondent numbers aren't known yet, in long format. Don't stack wide files of different cohorts that share column names (e.g.LAS2B046.SAVbelowLASAB046.SAV, orLASAZDC2.SAVbelowLASAZDC1.SAV): stack them in long format;a mix: long data that wide columns were merged into by
respnr, for example a Z file's – without the placeholder"Wave"columnread_lasa_sav()gives a Z file, or the two"Wave"columns end up asWave.xandWave.y, which is an error.format = "long"moves each wide column's values to its wave's row, adding a row where a respondent has a value at a wave the long data don't have a row for yet. On those added rows, stable variables the label database documents (such assex) are filled in from the respondent's other rows, and other columns are left missing, since they weren't measured at that wave. Merged withall = TRUE(ordplyr::full_join()), the respondents the long data lack get a row without a wave, holding the wide data's values: those of wide columns go to their waves, adding the rows they need (a row at every wave of the wide columns if there are none), and the others hold for every wave, as in wide data, so they fill each of the respondent's rows (a value in a"Time"column, or in a column of a wave-specific variable the label database documents, needs a wave, so it is an error). Where no wide columns were merged in, such respondents have no row in long format (with a message), but one in wide format.
Wide format has one row per respondent and drops the "Wave" and
"Time" columns. Each wave-specific variable gets one column per wave
at which it has any value, and a long column made from wide columns gets
all of those columns back, also ones without any value. With
prefix = "Wave", a column's name is its wave's lowercase LASA prefix
followed by the variable name: boak, coak, doak, ... Waves 2B, 3B,
4B, and MB get the prefixes b2, b3, b4, and mb (as LASA's own
zoa2/zoa3 files do for 2B and 3B), so they don't collide with wave
B's columns. Where LASA's own name for the variable at that wave stands
for nothing else, the column gets that name instead (m15wrth is
bm15twtrh at wave B and c15wtrth at wave C; totalalpha, wave H's
name without a wave prefix, stays totalalpha). A column that came from
a wide LASA file gets its original name back (e.g. t2_dat rather than
bt_dat), unless its values went to several waves or the name doesn't
say its wave by itself: the b_dm column of LASAZDC2.SAV, which holds
the second cohort's baseline, becomes b2dm.
With prefix = "Time", names are t, the "Time", and an underscore
followed by the variable name: t0_oak holds each respondent's value at
their own baseline, t1_oak at their cohort's next wave (wave C for the
first cohort, F for the second), and so on, so the cohorts share
columns. A cohort column after respnr gives each respondent's
cohort, which transforming the data back to long format uses. It is
LASA's cohort variable the way read_lasa_sav() reads LASAZ002.SAV's
– a factor of its value labels ("cohort 1 (1992)", "cohort 2 (2002)", "cohort 3 (2012)"), with its labels – so the result merges
with that file by respnr and cohort, read with to_factor = TRUE
(the default); read with to_factor = FALSE, merge it by respnr
alone (the cohort.x and cohort.y columns that gives are combined,
see above). The fourth cohort, whose code 4 the label database doesn't
document yet, gets the level "4", as read_lasa_sav() reads that
code, and the migrant cohort, which LASAZ002.SAV doesn't have, the
level "migrant cohort" after it. These levels come where the data have
respondents of these cohorts – "4" also with only the migrant
cohort's – so that each cohort keeps its code (1 to 5) when the factor
becomes numbers (in a .sav file, say). The column replaces a cohort
column data have, which must then be LASA's: any other column named
cohort (in any capitalization) is an error, so rename it first. Wave
A, which has no Time, keeps its own column (aoak). Every other value
needs a Time: values at a wave without one for their respondent are an
error, except missing-value codes, which are left out with a message. A
respondent whose rows have a Time while the data leave their cohort
open (rows of waves I to L only, which the third and the migrant cohort
give the same Time, of a respondent whose number doesn't say the
cohort, or says one the data rule out) gets a missing cohort, with a
warning: their columns can't be transformed back, also not by their
respondent number. A column holding several cohorts' waves (t0_oak: B,
2B, ...) gets those waves' types, value labels and user-missing codes,
combined the way long format combines waves, with a warning where their
user-missing codes don't combine, and their "wave_label"/"labels_wave"
as one entry per wave.
Original names aren't kept with prefix = "Time", also not when such
data are made wide again with prefix = "Wave".
A column stays stable in wide format when it has a single value per
respondent and isn't a documented wave-specific variable; a documented
stable variable (such as sex) only needs to agree across the rows
where it isn't missing. A wide column whose name still doesn't say which
wave and variable it holds (a name the label database doesn't document,
or a wave B name the later cohorts' baselines share, such as
blphya01, and, in a result with wave 4B, whose files use the
baselines' b names, any baseline's b name) carries the attributes
"LASA_wave" and "LASA_long_name", which transforming it back uses,
also without the result's other columns. Base R's merge() and row
subsetting drop those attributes from factor and numeric columns
(haven's labelled columns keep them); the column is then placed like a
column of LASA's own files, see Names of several waves.
Labels travel with the data. A long column keeps each wave's own
"wave_label"/"labels_wave" as one entry per wave. Its variable label
is the one its waves share, or else their harmonized (cross-wave)
label, or else the first wave's. Its value labels are those of all
waves combined; if a code is labelled differently at different waves,
it gets the harmonized value labels, or none. SPSS user-missing codes
("na_values", "na_range") are combined as long as that marks exactly
the same values missing on every wave's rows; otherwise the long column
gets none, with a warning. Factor levels are combined across waves;
wave-specific columns whose types don't combine (e.g. a factor at one
wave and numbers at another) become text, without value labels or
user-missing codes, with a warning. Time spans (difftime) get a unit
every wave's values convert to exactly, the first wave's if possible;
date-times that become text are written in UTC
("2021-10-31 00:30:00+0000"), so they read back as the same moment.
Converting back to wide restores each wide column's original type (also
from text), attributes, and user-missing codes, as long as its values
still fit them.
In long data, the column of a wave-specific variable the label database
documents that has lost its labels – rbind(), dplyr::bind_rows()
and merge() drop them from factor and numeric columns, and rbind()
keeps one file's for all rows of labelled columns – gets back the
labels read_lasa_sav() gives the variable at each wave it has values
at, from the label database: "wave_label"/"labels_wave" with an
entry per wave, "canonical_name", the harmonized label and value
labels where the database has them, and as "label" and "labels"
the harmonized ones, or else the waves' shared (or first) wording and
all their value labels. The data then get a "variable.labels"
attribute too, if they had none. So does a long column made of wide
columns that have all lost their labels (wide files merged with
merge()); wide format gives those columns back as they were. Labels
of a column's own (not ones the database gives the variable, such as a
user's own wording) are kept as they are, and a column with
"wave_label" entries for some of its waves only gets the other
waves', as long as those it has are the database's. A wave at which the
database documents the variable with different labels in several files
(partner at wave MB) gets none.
See also
read_lasa_sav() (format_as_long), apply_lasa_labels(),
lasa_label_db()
Examples
# A Z-file-shaped data frame: knee osteoarthritis (oak) of two
# respondents of the first cohort (waves B, C, and F) and one of the
# second (waves 2B and F), plus a stable variable (sex).
wide <- data.frame(
respnr = c(101, 102, 201),
sex = c(1, 2, 2),
boak = c(0, 2, NA),
coak = c(1, 8, NA),
b2oak = c(NA, NA, 1),
foak = c(2, NA, 0)
)
# format = "long" is the default. Time counts the waves since each
# respondent's own baseline: wave F is Time 4 for the first cohort, but
# Time 1 for the second.
long <- transform_lasa_data(wide)
long
#> respnr Wave Time sex oak
#> 1 101 B 0 1 0
#> 2 101 C 1 1 1
#> 3 101 F 4 1 2
#> 4 102 B 0 2 2
#> 5 102 C 1 2 8
#> 6 201 2B 0 2 1
#> 7 201 F 1 2 0
# And back again, with wave letters or Time numbers as prefixes:
transform_lasa_data(long, format = "wide")
#> respnr sex boak coak b2oak foak
#> 1 101 1 0 1 NA 2
#> 2 102 2 2 8 NA NA
#> 3 201 2 NA NA 1 0
transform_lasa_data(long, format = "wide", prefix = "Time")
#> respnr cohort sex t0_oak t1_oak t4_oak
#> 1 101 cohort 1 (1992) 1 0 1 2
#> 2 102 cohort 1 (1992) 2 2 8 NA
#> 3 201 cohort 2 (2002) 2 1 0 NA
if (FALSE) { # \dontrun{
# Read a Z file straight into long format:
oa <- read_lasa_sav("LASAZOA1.SAV", format_as_long = TRUE)
} # }