diff --git a/404.html b/404.html index 414a5e3..5552930 100644 --- a/404.html +++ b/404.html @@ -28,7 +28,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/LICENSE.html b/LICENSE.html index 2b6ae1a..67e8c28 100644 --- a/LICENSE.html +++ b/LICENSE.html @@ -7,7 +7,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/articles/coded-data.html b/articles/coded-data.html index 4bb395e..29d6eb3 100644 --- a/articles/coded-data.html +++ b/articles/coded-data.html @@ -27,7 +27,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/articles/extended-column-types.html b/articles/extended-column-types.html index e59f767..b3c4da3 100644 --- a/articles/extended-column-types.html +++ b/articles/extended-column-types.html @@ -27,7 +27,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/articles/index.html b/articles/index.html index cae6446..4615b0e 100644 --- a/articles/index.html +++ b/articles/index.html @@ -7,7 +7,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/articles/interlacer.html b/articles/interlacer.html index 4111671..772f49d 100644 --- a/articles/interlacer.html +++ b/articles/interlacer.html @@ -27,7 +27,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/articles/other-approaches.html b/articles/other-approaches.html index 27f2fa4..3de0fe9 100644 --- a/articles/other-approaches.html +++ b/articles/other-approaches.html @@ -27,7 +27,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/authors.html b/authors.html index 332154c..f6265fa 100644 --- a/authors.html +++ b/authors.html @@ -7,7 +7,7 @@ interlacer - 0.4.0 + 0.4.1 @@ -51,13 +51,13 @@ Citation Husmann K (2024). interlacer: Read Tabular Data With Interlaced Values And Missing Reasons. -R package version 0.4.0, https://kylehusmann.com/interlacer, https://github.com/khusmann/interlacer. +R package version 0.4.1, https://kylehusmann.com/interlacer, https://github.com/khusmann/interlacer. @Manual{, title = {interlacer: Read Tabular Data With Interlaced Values And Missing Reasons}, author = {Kyle Husmann}, year = {2024}, - note = {R package version 0.4.0, https://kylehusmann.com/interlacer}, + note = {R package version 0.4.1, https://kylehusmann.com/interlacer}, url = {https://github.com/khusmann/interlacer}, } diff --git a/index.html b/index.html index 102fe1b..b204290 100644 --- a/index.html +++ b/index.html @@ -17,8 +17,8 @@ - - + + @@ -30,7 +30,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/pkgdown.yml b/pkgdown.yml index a951c84..adf72c6 100644 --- a/pkgdown.yml +++ b/pkgdown.yml @@ -6,7 +6,7 @@ articles: extended-column-types: extended-column-types.html interlacer: interlacer.html other-approaches: other-approaches.html -last_built: 2024-10-12T00:52Z +last_built: 2024-10-12T01:41Z urls: reference: http://kylehusmann.com/interlacer/reference article: http://kylehusmann.com/interlacer/articles diff --git a/reference/across_value_channels.html b/reference/across_value_channels.html index fbd37cc..09e9846 100644 --- a/reference/across_value_channels.html +++ b/reference/across_value_channels.html @@ -11,7 +11,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/as.cfactor.html b/reference/as.cfactor.html index a510635..e773e79 100644 --- a/reference/as.cfactor.html +++ b/reference/as.cfactor.html @@ -7,7 +7,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/as.codes.html b/reference/as.codes.html index 0beb958..667d174 100644 --- a/reference/as.codes.html +++ b/reference/as.codes.html @@ -7,7 +7,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/as.x_col_spec.html b/reference/as.x_col_spec.html index 2d0e984..4754757 100644 --- a/reference/as.x_col_spec.html +++ b/reference/as.x_col_spec.html @@ -11,7 +11,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/as.x_collector.html b/reference/as.x_collector.html index 094a82a..76622a5 100644 --- a/reference/as.x_collector.html +++ b/reference/as.x_collector.html @@ -11,7 +11,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/cfactor.html b/reference/cfactor.html index 4b5f318..e25a285 100644 --- a/reference/cfactor.html +++ b/reference/cfactor.html @@ -7,7 +7,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/codes-set.html b/reference/codes-set.html index a630974..0db06f5 100644 --- a/reference/codes-set.html +++ b/reference/codes-set.html @@ -7,7 +7,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/codes.html b/reference/codes.html index eae129a..c92202e 100644 --- a/reference/codes.html +++ b/reference/codes.html @@ -7,7 +7,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/flatten_channels.html b/reference/flatten_channels.html index 3b0d643..abf521b 100644 --- a/reference/flatten_channels.html +++ b/reference/flatten_channels.html @@ -11,7 +11,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/grapes-equals-grapes.html b/reference/grapes-equals-grapes.html index 690de0b..05d1b61 100644 --- a/reference/grapes-equals-grapes.html +++ b/reference/grapes-equals-grapes.html @@ -25,7 +25,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/index.html b/reference/index.html index 7cad4ec..5ef044f 100644 --- a/reference/index.html +++ b/reference/index.html @@ -7,7 +7,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/interlaced.html b/reference/interlaced.html index 7e08d45..c575ca2 100644 --- a/reference/interlaced.html +++ b/reference/interlaced.html @@ -13,7 +13,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/interlacer_example.html b/reference/interlacer_example.html index d461413..ec5a8f4 100644 --- a/reference/interlacer_example.html +++ b/reference/interlacer_example.html @@ -9,7 +9,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/levels-set-.interlacer_interlaced.html b/reference/levels-set-.interlacer_interlaced.html index 1c9e5fd..0d41926 100644 --- a/reference/levels-set-.interlacer_interlaced.html +++ b/reference/levels-set-.interlacer_interlaced.html @@ -7,7 +7,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/levels.interlacer_interlaced.html b/reference/levels.interlacer_interlaced.html index f6b9eb2..3e347d6 100644 --- a/reference/levels.interlacer_interlaced.html +++ b/reference/levels.interlacer_interlaced.html @@ -13,7 +13,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/map_value_channel.html b/reference/map_value_channel.html index e8b86e1..4806833 100644 --- a/reference/map_value_channel.html +++ b/reference/map_value_channel.html @@ -11,7 +11,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/na.html b/reference/na.html index e4eb4a2..951f03a 100644 --- a/reference/na.html +++ b/reference/na.html @@ -7,7 +7,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/na_collectors.html b/reference/na_collectors.html index e76163f..e90a8fb 100644 --- a/reference/na_collectors.html +++ b/reference/na_collectors.html @@ -9,7 +9,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/parse_interlaced.html b/reference/parse_interlaced.html index 4738dc7..86bf702 100644 --- a/reference/parse_interlaced.html +++ b/reference/parse_interlaced.html @@ -9,7 +9,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/read_interlaced_delim.html b/reference/read_interlaced_delim.html index 0f9217b..ce92351 100644 --- a/reference/read_interlaced_delim.html +++ b/reference/read_interlaced_delim.html @@ -13,7 +13,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/reexports.html b/reference/reexports.html index 6562501..054fcf6 100644 --- a/reference/reexports.html +++ b/reference/reexports.html @@ -29,7 +29,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/value_channel.html b/reference/value_channel.html index 6a3dce4..c1a3d00 100644 --- a/reference/value_channel.html +++ b/reference/value_channel.html @@ -17,7 +17,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/value_collectors.html b/reference/value_collectors.html index eae6c57..3dfa1ad 100644 --- a/reference/value_collectors.html +++ b/reference/value_collectors.html @@ -11,7 +11,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/where_value_channel.html b/reference/where_value_channel.html index dd3d984..3a3c97e 100644 --- a/reference/where_value_channel.html +++ b/reference/where_value_channel.html @@ -11,7 +11,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/write_interlaced_delim.html b/reference/write_interlaced_delim.html index d92ae76..d247bc5 100644 --- a/reference/write_interlaced_delim.html +++ b/reference/write_interlaced_delim.html @@ -13,7 +13,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/x_col.html b/reference/x_col.html index 436588b..9c2eef0 100644 --- a/reference/x_col.html +++ b/reference/x_col.html @@ -11,7 +11,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/x_cols.html b/reference/x_cols.html index 68a352c..be180a8 100644 --- a/reference/x_cols.html +++ b/reference/x_cols.html @@ -11,7 +11,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/reference/x_spec.html b/reference/x_spec.html index 041856b..9b9ee0d 100644 --- a/reference/x_spec.html +++ b/reference/x_spec.html @@ -9,7 +9,7 @@ interlacer - 0.4.0 + 0.4.1 diff --git a/search.json b/search.json index 010953c..1942f59 100644 --- a/search.json +++ b/search.json @@ -1 +1 @@ -[{"path":"http://kylehusmann.com/interlacer/LICENSE.html","id":null,"dir":"","previous_headings":"","what":"Apache License","title":"Apache License","text":"Version 2.0, January 2004 ","code":""},{"path":[]},{"path":"http://kylehusmann.com/interlacer/LICENSE.html","id":"id_1-definitions","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"1. Definitions","title":"Apache License","text":"“License” shall mean terms conditions use, reproduction, distribution defined Sections 1 9 document. “Licensor” shall mean copyright owner entity authorized copyright owner granting License. “Legal Entity” shall mean union acting entity entities control, controlled , common control entity. purposes definition, “control” means () power, direct indirect, cause direction management entity, whether contract otherwise, (ii) ownership fifty percent (50%) outstanding shares, (iii) beneficial ownership entity. “” (“”) shall mean individual Legal Entity exercising permissions granted License. “Source” form shall mean preferred form making modifications, including limited software source code, documentation source, configuration files. “Object” form shall mean form resulting mechanical transformation translation Source form, including limited compiled object code, generated documentation, conversions media types. “Work” shall mean work authorship, whether Source Object form, made available License, indicated copyright notice included attached work (example provided Appendix ). “Derivative Works” shall mean work, whether Source Object form, based (derived ) Work editorial revisions, annotations, elaborations, modifications represent, whole, original work authorship. purposes License, Derivative Works shall include works remain separable , merely link (bind name) interfaces , Work Derivative Works thereof. “Contribution” shall mean work authorship, including original version Work modifications additions Work Derivative Works thereof, intentionally submitted Licensor inclusion Work copyright owner individual Legal Entity authorized submit behalf copyright owner. purposes definition, “submitted” means form electronic, verbal, written communication sent Licensor representatives, including limited communication electronic mailing lists, source code control systems, issue tracking systems managed , behalf , Licensor purpose discussing improving Work, excluding communication conspicuously marked otherwise designated writing copyright owner “Contribution.” “Contributor” shall mean Licensor individual Legal Entity behalf Contribution received Licensor subsequently incorporated within Work.","code":""},{"path":"http://kylehusmann.com/interlacer/LICENSE.html","id":"id_2-grant-of-copyright-license","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"2. Grant of Copyright License","title":"Apache License","text":"Subject terms conditions License, Contributor hereby grants perpetual, worldwide, non-exclusive, -charge, royalty-free, irrevocable copyright license reproduce, prepare Derivative Works , publicly display, publicly perform, sublicense, distribute Work Derivative Works Source Object form.","code":""},{"path":"http://kylehusmann.com/interlacer/LICENSE.html","id":"id_3-grant-of-patent-license","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"3. Grant of Patent License","title":"Apache License","text":"Subject terms conditions License, Contributor hereby grants perpetual, worldwide, non-exclusive, -charge, royalty-free, irrevocable (except stated section) patent license make, made, use, offer sell, sell, import, otherwise transfer Work, license applies patent claims licensable Contributor necessarily infringed Contribution(s) alone combination Contribution(s) Work Contribution(s) submitted. institute patent litigation entity (including cross-claim counterclaim lawsuit) alleging Work Contribution incorporated within Work constitutes direct contributory patent infringement, patent licenses granted License Work shall terminate date litigation filed.","code":""},{"path":"http://kylehusmann.com/interlacer/LICENSE.html","id":"id_4-redistribution","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"4. Redistribution","title":"Apache License","text":"may reproduce distribute copies Work Derivative Works thereof medium, without modifications, Source Object form, provided meet following conditions: () must give recipients Work Derivative Works copy License; (b) must cause modified files carry prominent notices stating changed files; (c) must retain, Source form Derivative Works distribute, copyright, patent, trademark, attribution notices Source form Work, excluding notices pertain part Derivative Works; (d) Work includes “NOTICE” text file part distribution, Derivative Works distribute must include readable copy attribution notices contained within NOTICE file, excluding notices pertain part Derivative Works, least one following places: within NOTICE text file distributed part Derivative Works; within Source form documentation, provided along Derivative Works; , within display generated Derivative Works, wherever third-party notices normally appear. contents NOTICE file informational purposes modify License. may add attribution notices within Derivative Works distribute, alongside addendum NOTICE text Work, provided additional attribution notices construed modifying License. may add copyright statement modifications may provide additional different license terms conditions use, reproduction, distribution modifications, Derivative Works whole, provided use, reproduction, distribution Work otherwise complies conditions stated License.","code":""},{"path":"http://kylehusmann.com/interlacer/LICENSE.html","id":"id_5-submission-of-contributions","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"5. Submission of Contributions","title":"Apache License","text":"Unless explicitly state otherwise, Contribution intentionally submitted inclusion Work Licensor shall terms conditions License, without additional terms conditions. Notwithstanding , nothing herein shall supersede modify terms separate license agreement may executed Licensor regarding Contributions.","code":""},{"path":"http://kylehusmann.com/interlacer/LICENSE.html","id":"id_6-trademarks","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"6. Trademarks","title":"Apache License","text":"License grant permission use trade names, trademarks, service marks, product names Licensor, except required reasonable customary use describing origin Work reproducing content NOTICE file.","code":""},{"path":"http://kylehusmann.com/interlacer/LICENSE.html","id":"id_7-disclaimer-of-warranty","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"7. Disclaimer of Warranty","title":"Apache License","text":"Unless required applicable law agreed writing, Licensor provides Work (Contributor provides Contributions) “” BASIS, WITHOUT WARRANTIES CONDITIONS KIND, either express implied, including, without limitation, warranties conditions TITLE, NON-INFRINGEMENT, MERCHANTABILITY, FITNESS PARTICULAR PURPOSE. solely responsible determining appropriateness using redistributing Work assume risks associated exercise permissions License.","code":""},{"path":"http://kylehusmann.com/interlacer/LICENSE.html","id":"id_8-limitation-of-liability","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"8. Limitation of Liability","title":"Apache License","text":"event legal theory, whether tort (including negligence), contract, otherwise, unless required applicable law (deliberate grossly negligent acts) agreed writing, shall Contributor liable damages, including direct, indirect, special, incidental, consequential damages character arising result License use inability use Work (including limited damages loss goodwill, work stoppage, computer failure malfunction, commercial damages losses), even Contributor advised possibility damages.","code":""},{"path":"http://kylehusmann.com/interlacer/LICENSE.html","id":"id_9-accepting-warranty-or-additional-liability","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"9. Accepting Warranty or Additional Liability","title":"Apache License","text":"redistributing Work Derivative Works thereof, may choose offer, charge fee , acceptance support, warranty, indemnity, liability obligations /rights consistent License. However, accepting obligations, may act behalf sole responsibility, behalf Contributor, agree indemnify, defend, hold Contributor harmless liability incurred , claims asserted , Contributor reason accepting warranty additional liability. END TERMS CONDITIONS","code":""},{"path":"http://kylehusmann.com/interlacer/LICENSE.html","id":"appendix-how-to-apply-the-apache-license-to-your-work","dir":"","previous_headings":"","what":"APPENDIX: How to apply the Apache License to your work","title":"Apache License","text":"apply Apache License work, attach following boilerplate notice, fields enclosed brackets [] replaced identifying information. (Don’t include brackets!) text enclosed appropriate comment syntax file format. also recommend file class name description purpose included “printed page” copyright notice easier identification within third-party archives.","code":"Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License."},{"path":"http://kylehusmann.com/interlacer/articles/coded-data.html","id":"warning","dir":"Articles","previous_headings":"","what":"⚠️ ⚠️ ⚠️ WARNING ⚠️ ⚠️ ⚠️","title":"Coded Data","text":"cfactor type highly experimental feature (even compared rest interlacer) thoroughly tested! ’m sharing super pre-alpha, unstable state get feedback invest time polishing implementation.","code":""},{"path":"http://kylehusmann.com/interlacer/articles/coded-data.html","id":"spss-style-codes","dir":"Articles","previous_headings":"","what":"SPSS-style codes","title":"Coded Data","text":"motivating example, consider coded version colors.csv example: missing reasons : -99: N/-98: REFUSED -97: OMITTED colors coded: 1: BLUE 2: RED 3: YELLOW style coding, positive values representing categorical levels negative values representing missing values, common format used SPSS. data can loaded interlaced numeric values follows: representation awkward work codes meaningless obfuscate significance code write results output. wanted select everyone BLUE favorite color, example, write: Similarly, wanted filter OMITTED favorite colors, write: make data ergnomic work , can use interlacer’s v_col_cfactor() na_col_cfactor() collector types load values cfactor instead, allows associate codes human-readable labels: Now human-readable labels, instead magic codes, can used working data: can still convert labels values missing reasons back codes wish, using .codes(). following convert missing reason channel age value channel favorite_color coded representation: recode cfactor channels data frame coded representation can following:","code":"library(readr) library(dplyr, warn.conflicts = FALSE) library(interlacer, warn.conflicts = FALSE) read_file( interlacer_example(\"colors_coded.csv\") ) |> cat() #> person_id,age,favorite_color #> 1,20,1 #> 2,-98,1 #> 3,21,-98 #> 4,30,-97 #> 5,1,-99 #> 6,41,2 #> 7,50,-97 #> 8,30,3 #> 9,-98,-98 #> 10,-97,2 #> 11,10,-98 (df_coded <- read_interlaced_csv( interlacer_example(\"colors_coded.csv\"), na = c(-99, -98, -97) )) #> # A tibble: 11 × 3 #> person_id age favorite_color #> #> 1 1 20 1 #> 2 2 <-98> 1 #> 3 3 21 <-98> #> 4 4 30 <-97> #> 5 5 1 <-99> #> 6 6 41 2 #> 7 7 50 <-97> #> 8 8 30 3 #> 9 9 <-98> <-98> #> 10 10 <-97> 2 #> 11 11 10 <-98> df_coded |> filter(favorite_color == 1) #> # A tibble: 2 × 3 #> person_id age favorite_color #> #> 1 1 20 1 #> 2 2 <-98> 1 df_coded |> filter(favorite_color == na(-97)) #> # A tibble: 0 × 3 #> # ℹ 3 variables: person_id , age , favorite_color (df_decoded <- read_interlaced_csv( interlacer_example(\"colors_coded.csv\"), col_types = x_cols( favorite_color = v_col_cfactor(codes = c(BLUE = 1, RED = 2, YELLOW = 3)), ), na = na_col_cfactor(REFUSED = -99, OMITTED = -98, `N/A` = -97) )) #> # A tibble: 11 × 3 #> person_id age favorite_color #> #> 1 1 20 BLUE #> 2 2 BLUE #> 3 3 21 #> 4 4 30 #> 5 5 1 #> 6 6 41 RED #> 7 7 50 #> 8 8 30 YELLOW #> 9 9 #> 10 10 RED #> 11 11 10 df_decoded |> filter(favorite_color == \"BLUE\") #> # A tibble: 2 × 3 #> person_id age favorite_color #> #> 1 1 20 BLUE #> 2 2 BLUE df_decoded |> filter(favorite_color == na(\"OMITTED\")) #> # A tibble: 0 × 3 #> # ℹ 3 variables: person_id , age , #> # favorite_color df_decoded |> mutate( age = map_na_channel(age, as.codes), favorite_color = map_value_channel(favorite_color, as.codes) ) #> # A tibble: 11 × 3 #> person_id age favorite_color #> #> 1 1 20 1 #> 2 2 <-98> 1 #> 3 3 21 #> 4 4 30 #> 5 5 1 #> 6 6 41 2 #> 7 7 50 #> 8 8 30 3 #> 9 9 <-98> #> 10 10 <-97> 2 #> 11 11 10 df_decoded |> mutate( across_value_channels(where_value_channel(is.cfactor), as.codes), across_na_channels(where_na_channel(is.cfactor), as.codes), ) #> # A tibble: 11 × 3 #> person_id age favorite_color #> #> 1 1 20 1 #> 2 2 <-98> 1 #> 3 3 21 <-98> #> 4 4 30 <-97> #> 5 5 1 <-99> #> 6 6 41 2 #> 7 7 50 <-97> #> 8 8 30 3 #> 9 9 <-98> <-98> #> 10 10 <-97> 2 #> 11 11 10 <-98>"},{"path":"http://kylehusmann.com/interlacer/articles/coded-data.html","id":"sas--and-stata-style-codes","dir":"Articles","previous_headings":"","what":"SAS- and Stata-style codes","title":"Coded Data","text":"Like SPSS, SAS Stata encode factor levels numeric values, instead representing missing reasons negative codes, given character codes: example, value coding scheme used favorite_color previous example, except missing reason channels coded follows: “.”: N/“.”: REFUSED “.b”: OMITTED data can easily loaded interlacer cfactor missing reason channel follows:","code":"read_file( interlacer_example(\"colors_coded_char.csv\") ) |> cat() #> person_id,age,favorite_color #> 1,20,1 #> 2,.a,1 #> 3,21,.a #> 4,30,.b #> 5,1,. #> 6,41,2 #> 7,50,.b #> 8,30,3 #> 9,.a,.a #> 10,.b,2 #> 11,10,.a read_interlaced_csv( interlacer_example(\"colors_coded_char.csv\"), col_types = x_cols( favorite_color = v_col_cfactor(codes = c(BLUE = 1, RED = 2, YELLOW = 3)), ), na = c(`N/A` = \".\", REFUSED = \".a\", OMITTED = \".b\"), ) #> # A tibble: 11 × 3 #> person_id age favorite_color #> #> 1 1 20 BLUE #> 2 2 BLUE #> 3 3 21 #> 4 4 30 #> 5 5 1 #> 6 6 41 RED #> 7 7 50 #> 8 8 30 YELLOW #> 9 9 #> 10 10 RED #> 11 11 10 "},{"path":"http://kylehusmann.com/interlacer/articles/coded-data.html","id":"the-cfactor-type","dir":"Articles","previous_headings":"","what":"The cfactor type","title":"Coded Data","text":"cfactor extension base R’s factor type. created numeric character codes using cfactor() function: cfactor vectors can used wherever regular base R factor types used, fully-compatible factor types: unlike regular factor, cfactor additionally stores codes factor levels. means can convert back coded representation time, desired: IMPORTANT: .numeric() .integer() functions convert cfactor numeric codes coded representation. Instead, order retain full compatibility base R factor type, always returns result coded index level factor: levels changed, cfactor drop codes degrade regular R factor: Finally, base R factor character vector labels, can add codes via .cfactor():","code":"(example_cfactor <- cfactor( c(10, 20, 30, 10, 20, 30), codes = c(LEVEL_A = 10, LEVEL_B = 20, LEVEL_C = 30) )) #> [6]> #> [1] LEVEL_A LEVEL_B LEVEL_C LEVEL_A LEVEL_B LEVEL_C #> #> Categorical levels: #> label code #> LEVEL_A 10 #> LEVEL_B 20 #> LEVEL_C 30 (example_cfactor2 <- cfactor( c(\"a\", \"b\", \"c\", \"a\", \"b\", \"c\"), codes = c(LEVEL_A = \"a\", LEVEL_B = \"b\", LEVEL_C = \"c\") )) #> [6]> #> [1] LEVEL_A LEVEL_B LEVEL_C LEVEL_A LEVEL_B LEVEL_C #> #> Categorical levels: #> label code #> LEVEL_A a #> LEVEL_B b #> LEVEL_C c is.factor(example_cfactor) #> [1] TRUE levels(example_cfactor) #> [1] \"LEVEL_A\" \"LEVEL_B\" \"LEVEL_C\" is.factor(example_cfactor2) #> [1] TRUE levels(example_cfactor2) #> [1] \"LEVEL_A\" \"LEVEL_B\" \"LEVEL_C\" codes(example_cfactor) #> LEVEL_A LEVEL_B LEVEL_C #> 10 20 30 as.codes(example_cfactor) #> [1] 10 20 30 10 20 30 codes(example_cfactor2) #> LEVEL_A LEVEL_B LEVEL_C #> \"a\" \"b\" \"c\" as.codes(example_cfactor2) #> [1] \"a\" \"b\" \"c\" \"a\" \"b\" \"c\" as.numeric(example_cfactor) #> [1] 1 2 3 1 2 3 as.numeric(example_cfactor2) #> [1] 1 2 3 1 2 3 cfactor_copy <- example_cfactor # cfactory_copy is a cfactor and a factor is.cfactor(cfactor_copy) #> [1] TRUE is.factor(cfactor_copy) #> [1] TRUE levels(cfactor_copy) #> [1] \"LEVEL_A\" \"LEVEL_B\" \"LEVEL_C\" codes(cfactor_copy) #> LEVEL_A LEVEL_B LEVEL_C #> 10 20 30 # modify the levels of the cfactor as if it was a regular factor levels(cfactor_copy) <- c(\"C\", \"B\", \"A\") # now cfactor_copy is just a regular factor is.cfactor(cfactor_copy) #> [1] FALSE is.factor(cfactor_copy) #> [1] TRUE levels(cfactor_copy) #> [1] \"C\" \"B\" \"A\" codes(cfactor_copy) #> NULL as.cfactor( c(\"LEVEL_A\", \"LEVEL_B\", \"LEVEL_C\", \"LEVEL_A\", \"LEVEL_B\", \"LEVEL_C\"), codes = c(LEVEL_A = 10, LEVEL_B = 20, LEVEL_C = 30) ) #> [6]> #> [1] LEVEL_A LEVEL_B LEVEL_C LEVEL_A LEVEL_B LEVEL_C #> #> Categorical levels: #> label code #> LEVEL_A 10 #> LEVEL_B 20 #> LEVEL_C 30"},{"path":"http://kylehusmann.com/interlacer/articles/coded-data.html","id":"re-coding-and-writing-an-interlaced-data-frame-","dir":"Articles","previous_headings":"","what":"Re-coding and writing an interlaced data frame.","title":"Coded Data","text":"Re-coding writing interlaced data frame simple calling .codes() cfactor type value missing reason channels, calling one write_interlaced_*() family functions:","code":"df_decoded |> mutate( across_value_channels(where_value_channel(is.cfactor), as.codes), across_na_channels(where_na_channel(is.cfactor), as.codes), ) |> write_interlaced_csv(\"output.csv\")"},{"path":"http://kylehusmann.com/interlacer/articles/coded-data.html","id":"haven","dir":"Articles","previous_headings":"","what":"haven","title":"Coded Data","text":"haven package functions loading native SPSS, SAS, Stata native file formats special data frames use column attributes special values keep track value labels missing reasons. complete discussion compares interlacer’s approach, see vignette(\"-approaches\").","code":""},{"path":"http://kylehusmann.com/interlacer/articles/extended-column-types.html","id":"x_cols-extended-cols-specifications","dir":"Articles","previous_headings":"","what":"x_cols: extended cols specifications","title":"Extended Column Types","text":"need fine-grained control value missing reason channel types, can use x_cols() specification, extension readr’s readr::cols() system. x_cols(), can control value channel na channel types columns resulting data frame. useful missing reasons apply particular items opposed file whole. example, say measure following two items: current stress level? Low Moderate High don’t know don’t understand question well feel manage time responsibilities today? Poorly Fairly well Well well apply (Today vacation day) apply (reason) can see, items two selection choices mapped missing reasons. can specified x_cols() follows: Like readr’s readr::cols() function, named x_cols() describes column resulting data frame. Value missing reason channel types declared via calls v_col_*() na_col_*() respectively, assembled x_col(). v_col_*() types mirror readr’s readr::col_* column “collectors”. v_col_double() equivalent readr::col_double(), v_col_character() equivalent readr::col_character(), etc. See vroom’s documentation list available column types. na_col_*() collectors allow declare missing reason channel type loaded column, values interpreted missing reasons. Currently, five options: na_col_default(): Use collector defined na = argument read_interlaced_*() function na_col_none(): Load column without missing reason channel. na_col_factor(): Use factor missing reason channel. Character arguments passed form levels factor. (e.g. na_col_factor(\"REFUSED\", \"OMITTED\", \"N/\")) na_col_integer(): Use integer na channel. Numeric arguments passed values interpreted missing values. (e.g. na_col_integer(-99, -98, -97))) na_col_cfactor(): Use cfactor na channel. (cfactor types covered next vignette,vignette(\"coded-data\")) following example shows collectors action. example use coded version colors.csv example data, demonstrate integer missing reason types:","code":"(df_stress <- read_interlaced_csv( interlacer_example(\"stress.csv\"), col_types = x_cols( person_id = x_col( v_col_integer(), na_col_none() ), current_stress = x_col( v_col_factor(levels = c(\"LOW\", \"MODERATE\", \"HIGH\")), na_col_factor(\"DONT_KNOW\", \"DONT_UNDERSTAND\") ), time_management = x_col( v_col_factor(levels = c(\"POORLY\", \"FAIRLY_WELL\", \"WELL\", \"VERY_WELL\")), na_col_factor(\"NA_VACATION\", \"NA_OTHER\") ) ) )) #> # A tibble: 8 × 3 #> person_id current_stress time_management #> #> 1 1 LOW VERY_WELL #> 2 2 MODERATE POORLY #> 3 3 #> 4 4 HIGH POORLY #> 5 5 #> 6 6 LOW #> 7 7 MODERATE WELL #> 8 8 FAIRLY_WELL read_interlaced_csv( interlacer_example(\"colors_coded.csv\"), col_types = x_cols( person_id = x_col(v_col_integer(), na_col_none()), age = x_col(v_col_double(), na_col_integer(-99, -98, -97)), favorite_color = x_col(v_col_integer(), na_col_integer(-99, -98, -97)) ) ) #> # A tibble: 11 × 3 #> person_id age favorite_color #> #> 1 1 20 1 #> 2 2 <-98> 1 #> 3 3 21 <-98> #> 4 4 30 <-97> #> 5 5 1 <-99> #> 6 6 41 2 #> 7 7 50 <-97> #> 8 8 30 3 #> 9 9 <-98> <-98> #> 10 10 <-97> 2 #> 11 11 10 <-98>"},{"path":[]},{"path":"http://kylehusmann.com/interlacer/articles/extended-column-types.html","id":"default-collector-types","dir":"Articles","previous_headings":"Shortcuts","what":"Default collector types","title":"Extended Column Types","text":"Like readr’s cols() function, x_cols() function accepts .default argument specifies default value collector. na = argument similarly used specify default missing reason collector used na_col_*() specified, set na_col_default(). taking advantage defaults, specification last example equivalently written :","code":"read_interlaced_csv( interlacer_example(\"colors_coded.csv\"), col_types = x_cols( .default = v_col_integer(), person_id = x_col(v_col_integer(), na_col_none()), age = v_col_double(), ), na = na_col_integer(-99, -98, -97) ) #> # A tibble: 11 × 3 #> person_id age favorite_color #> #> 1 1 20 1 #> 2 2 <-98> 1 #> 3 3 21 <-98> #> 4 4 30 <-97> #> 5 5 1 <-99> #> 6 6 41 2 #> 7 7 50 <-97> #> 8 8 30 3 #> 9 9 <-98> <-98> #> 10 10 <-97> 2 #> 11 11 10 <-98>"},{"path":"http://kylehusmann.com/interlacer/articles/extended-column-types.html","id":"concise-value-and-missing-reason-specifications","dir":"Articles","previous_headings":"Shortcuts","what":"Concise value and missing reason specifications","title":"Extended Column Types","text":"Like readr, value collectors can specified using characters. example, instead v_col_integer(), can use \"\". See vroom’s documentation complete list shortcuts. Similarly, missing reason collectors can specified providing vector missing values; collector type inferred via type vector. conversions follows: na_col_none(): NULL na_col_factor(): character vector, e.g. c(\"REFUSED\", \"OMITTED\", \"N/\") na_col_integer(): numeric vector, e.g. c(-99, -98, -97)) na_col_cfactor(): named character numeric vector, e.g. c(REFUSED = -99, OMITTED = -98, `N/` = -97) Using shortcuts, previous example equivalently written compact form follows:","code":"read_interlaced_csv( interlacer_example(\"colors_coded.csv\"), col_types = x_cols( .default = \"i\", person_id = x_col(\"i\", NULL), age = \"d\", ), na = c(-99, -98, -97) ) #> # A tibble: 11 × 3 #> person_id age favorite_color #> #> 1 1 20 1 #> 2 2 <-98> 1 #> 3 3 21 <-98> #> 4 4 30 <-97> #> 5 5 1 <-99> #> 6 6 41 2 #> 7 7 50 <-97> #> 8 8 30 3 #> 9 9 <-98> <-98> #> 10 10 <-97> 2 #> 11 11 10 <-98>"},{"path":"http://kylehusmann.com/interlacer/articles/extended-column-types.html","id":"next-steps","dir":"Articles","previous_headings":"","what":"Next steps","title":"Extended Column Types","text":"vignette covered column types values missing reasons can explicitly specified using collectors. also illustrated column-level missing values can specified creating extended column type specifications using x_cols(). final examples, used example data set coded values missing reasons. Coded values especially common data sets produced SPSS, SAS, Stata. interlacer provides special column type make working sort data easier: cfactor type. covered next vignette, vignette(\"coded-data\").","code":""},{"path":"http://kylehusmann.com/interlacer/articles/interlacer.html","id":"aggregations-with-missing-reasons","dir":"Articles","previous_headings":"","what":"Aggregations with missing reasons","title":"Introduction to interlacer","text":"Now, interested values source data, functionality need. wanted know values NA? Although information encoded source data, lost missing reasons converted NA values. example, consider favorite_color column. many respondents REFUSED give favorite color? many people just OMITTED answer? question N/respondents (e.g. wasn’t survey form)? mean respondent age groups? current dataframe gets us part way: can see, converted missing reasons single NA, can answer questions missingness general, rather work specific reasons stored source data. Unfortunately, try load data missing reasons intact, lose something else: type information values. Now access missing reasons, columns character vectors. means order anything values, always filter missing reasons, cast remaining values desired type: gives us information want, cumbersome. Notice ’s distinction favorite color values missing reasons! Things start get really complex different columns different sets possible missing reasons. means lot type conversion gymnastics switch value types missing types.","code":"library(dplyr, warn.conflicts = FALSE) df_simple |> summarize( mean_age = mean(age, na.rm = TRUE), n = n(), .by = favorite_color ) |> arrange(favorite_color) #> # A tibble: 4 × 3 #> favorite_color mean_age n #> #> 1 BLUE 20 2 #> 2 RED 41 2 #> 3 YELLOW 30 1 #> 4 NA 22.4 6 (df_with_missing <- read_csv( interlacer_example(\"colors.csv\"), col_types = cols(.default = \"c\") )) #> # A tibble: 11 × 3 #> person_id age favorite_color #> #> 1 1 20 BLUE #> 2 2 REFUSED BLUE #> 3 3 21 REFUSED #> 4 4 30 OMITTED #> 5 5 1 N/A #> 6 6 41 RED #> 7 7 50 OMITTED #> 8 8 30 YELLOW #> 9 9 REFUSED REFUSED #> 10 10 OMITTED RED #> 11 11 10 REFUSED reasons <- c(\"REFUSED\", \"OMITTED\", \"N/A\") df_with_missing |> mutate( age_values = as.numeric(if_else(age %in% reasons, NA, age)), ) |> summarize( mean_age = mean(age_values, na.rm = TRUE), n = n(), .by = favorite_color ) |> arrange(favorite_color) #> # A tibble: 6 × 3 #> favorite_color mean_age n #> #> 1 BLUE 20 2 #> 2 N/A 1 1 #> 3 OMITTED 40 2 #> 4 RED 41 2 #> 5 REFUSED 15.5 3 #> 6 YELLOW 30 1"},{"path":"http://kylehusmann.com/interlacer/articles/interlacer.html","id":"the-interlacer-approach","dir":"Articles","previous_headings":"Aggregations with missing reasons","what":"The interlacer approach","title":"Introduction to interlacer","text":"interlacer built based insight everything becomes much tidy, simple, expressive explicitly work values missing reasons separate channels variable. interlacer introduces new interlaced column type facilitates . read_interlaced_* functions interlacer import data new column type. can see column headers, column loaded composed two channels: value channel, missing reason channel. channel can type. age column, example, double values factor missing reasons: channels can explicitly accessed using value_channel() na_channel() helper functions: helpers rarely needed, however, computations automatically operate interlaced column’s value channel, ignore missing reasons channel. following compute mean age, without missing reasons interfering: (equivalently used value_channel() helper achieve result, albeit verbosity): Although missing reasons excluded computations, still treated unique values. means group age get breakdown unique missing reasons, rather lumped single NA: can see, can generate report , without needing type gymnastics! Also, values neatly distinguished missing reasons.","code":"(df <- read_interlaced_csv( interlacer_example(\"colors.csv\"), na = c(\"REFUSED\", \"OMITTED\", \"N/A\") )) #> # A tibble: 11 × 3 #> person_id age favorite_color #> #> 1 1 20 BLUE #> 2 2 BLUE #> 3 3 21 #> 4 4 30 #> 5 5 1 #> 6 6 41 RED #> 7 7 50 #> 8 8 30 YELLOW #> 9 9 #> 10 10 RED #> 11 11 10 df$age #> [11]> #> [1] 20 21 30 1 41 50 #> [8] 30 10 #> NA levels: REFUSED OMITTED N/A value_channel(df$age) #> [1] 20 NA 21 30 1 41 50 30 NA NA 10 na_channel(df$age) #> [1] REFUSED REFUSED #> [10] OMITTED #> Levels: REFUSED OMITTED N/A mean(df$age, na.rm = TRUE) #> [1] 25.375 mean(value_channel(df$age), na.rm = TRUE) #> [1] 25.375 df |> summarize( mean_age = mean(age, na.rm = TRUE), n = n(), .by = favorite_color ) |> arrange(favorite_color) #> # A tibble: 4 × 3 #> favorite_color mean_age n #> #> 1 BLUE 20 2 #> 2 RED 41 2 #> 3 YELLOW 30 1 #> 4 22.4 6"},{"path":"http://kylehusmann.com/interlacer/articles/interlacer.html","id":"filtering-based-on-missing-reasons","dir":"Articles","previous_headings":"","what":"Filtering based on missing reasons","title":"Introduction to interlacer","text":"interlaced columns also helpful creating samples inclusion / exclusion criteria based missing reasons. example, using example data, say wanted create sample respondents REFUSED give age. indicate value interpreted missing reason, can use na() function value: people REFUSED report age favorite color? ’s also possible combine value conditions missing reason conditions. example, select everyone REFUSED give favorite color, 20 years old:","code":"df |> filter(age == na(\"REFUSED\")) #> # A tibble: 0 × 3 #> # ℹ 3 variables: person_id , age , favorite_color # na_channel() can also be used to get an equivalent result: df |> filter(na_channel(age) == \"REFUSED\") #> # A tibble: 2 × 3 #> person_id age favorite_color #> #> 1 2 BLUE #> 2 9 df |> filter(age == na(\"REFUSED\") & favorite_color == na(\"REFUSED\")) #> # A tibble: 0 × 3 #> # ℹ 3 variables: person_id , age , favorite_color df |> filter(age > 20 & favorite_color == na(\"REFUSED\")) #> # A tibble: 0 × 3 #> # ℹ 3 variables: person_id , age , favorite_color "},{"path":"http://kylehusmann.com/interlacer/articles/interlacer.html","id":"mutations","dir":"Articles","previous_headings":"","what":"Mutations","title":"Introduction to interlacer","text":"might expect, na() function can used values mutations. following pipeline replace favorite color respondents missing value \"REDACTED\" Conditionals also work exactly expect mutations. following replace favorite color respondents age < 18 missing reason \"REDACTED_UNDERAGE\". Respondents missing age replaced \"REDACTED_MISSING_AGE\" following mutation create new column called person_type \"CHILD\" age < 18, \"ADULT\" age >= 18, missing reason \"AGE_UNAVAILABLE\" age missing: Important note: must use dplyr::if_else() interlaced vectors instead R’s base::ifelse() function, base function strips missing reason channel due fundamental limitation base R.","code":"df |> mutate( favorite_color = na(\"REDACTED\") ) #> # A tibble: 11 × 3 #> person_id age favorite_color #> ??,fct> #> 1 1 20 #> 2 2 #> 3 3 21 #> 4 4 30 #> 5 5 1 #> 6 6 41 #> 7 7 50 #> 8 8 30 #> 9 9 #> 10 10 #> 11 11 10 df |> mutate( favorite_color = if_else( age < 18, na(\"REDACTED_UNDERAGE\"), favorite_color, missing = na(\"REDACTED_MISSING_AGE\") ) ) #> # A tibble: 11 × 3 #> person_id age favorite_color #> #> 1 1 20 BLUE #> 2 2 #> 3 3 21 #> 4 4 30 #> 5 5 1 #> 6 6 41 RED #> 7 7 50 #> 8 8 30 YELLOW #> 9 9 #> 10 10 #> 11 11 10 df |> mutate( person_type = if_else( age < 18, \"CHILD\", \"ADULT\", missing = na(\"AGE_UNAVAILABLE\") ), ) #> # A tibble: 11 × 4 #> person_id age favorite_color person_type #> #> 1 1 20 BLUE ADULT #> 2 2 BLUE #> 3 3 21 ADULT #> 4 4 30 ADULT #> 5 5 1 CHILD #> 6 6 41 RED ADULT #> 7 7 50 ADULT #> 8 8 30 YELLOW ADULT #> 9 9 #> 10 10 RED #> 11 11 10 CHILD"},{"path":"http://kylehusmann.com/interlacer/articles/interlacer.html","id":"multichannel-comparison","dir":"Articles","previous_headings":"","what":"Multichannel comparison","title":"Introduction to interlacer","text":"Comparison operators (e.g. == !=) compare value channels, return NA whenever missing values involved: means missing reasons directly compared: simultaneously compare values missing reason channels, interlacer provides multichannel comparison operators %==% %!=%. operators always return boolean vectors, never return missing values. multichannel comparison, two values considered equal iff: values, values equal missing values, reasons missing values, lack missing reasons way, convert previous example use multichannel comparison, get: Similarly, comparisons values return booleans rather NA, , consequence, regular NA values equivalent interlaced values missing reason: Missing values missing missing reasons called “empty values”, discussed next section.","code":"5 == NA #> [1] NA 5 == na(\"reason\") #> [1] NA na(\"reason1\") == na(\"reason2\") #> [1] NA na(\"reason1\") %==% na(\"reason2\") #> [1] FALSE 5 %==% NA #> [1] FALSE 5 %==% na(\"reason\") #> [1] FALSE NA %==% na() #> [1] TRUE # Alternatively this can be considered an `NA` missing reason: NA %==% na(NA) #> [1] TRUE"},{"path":"http://kylehusmann.com/interlacer/articles/interlacer.html","id":"empty-values","dir":"Articles","previous_headings":"","what":"Empty values","title":"Introduction to interlacer","text":"Empty values missing values lack missing reasons. values can arise missing actions specified. example, example, empty values created missing = argument if_else() statement specified: can see, empty values displayed <>. Empty values can detected using multichannel comparsion operator: (Note regular equality work, return NA comparisons!) Empty values often occur result joins, dplyr::*_join() family functions missing = parameter, like dplyr::if_else() . example, say following data frame wanted join sample: ’re missing condition information respondents, show empty values join data frame sample: can remedy replacing empty values join:","code":"df |> mutate( favorite_color = if_else( age < 18, na(\"REDACTED_UNDERAGE\"), favorite_color, ) ) #> # A tibble: 11 × 3 #> person_id age favorite_color #> #> 1 1 20 BLUE #> 2 2 <> #> 3 3 21 #> 4 4 30 #> 5 5 1 #> 6 6 41 RED #> 7 7 50 #> 8 8 30 YELLOW #> 9 9 <> #> 10 10 <> #> 11 11 10 df |> mutate( favorite_color = if_else( age < 18, na(\"REDACTED_UNDERAGE\"), favorite_color, ) ) |> filter(favorite_color %==% na()) #> # A tibble: 3 × 3 #> person_id age favorite_color #> #> 1 2 <> #> 2 9 <> #> 3 10 <> conditions <- tribble( ~person_id, ~condition, 1, \"TREATMENT\", 2, \"CONTROL\", 3, na(\"TECHNICAL_ERROR\"), 6, \"CONTROL\", 8, \"TREATMENT\", ) df |> left_join(conditions, by = join_by(person_id)) #> # A tibble: 11 × 4 #> person_id age favorite_color condition #> #> 1 1 20 BLUE TREATMENT #> 2 2 BLUE CONTROL #> 3 3 21 #> 4 4 30 <> #> 5 5 1 <> #> 6 6 41 RED CONTROL #> 7 7 50 <> #> 8 8 30 YELLOW TREATMENT #> 9 9 <> #> 10 10 RED <> #> 11 11 10 <> df |> left_join(conditions, by = join_by(person_id)) |> mutate( condition = if_else(condition %==% na(), na(\"LEFT_STUDY\"), condition), ) #> # A tibble: 11 × 4 #> person_id age favorite_color condition #>
Husmann K (2024). interlacer: Read Tabular Data With Interlaced Values And Missing Reasons. -R package version 0.4.0, https://kylehusmann.com/interlacer, https://github.com/khusmann/interlacer. +R package version 0.4.1, https://kylehusmann.com/interlacer, https://github.com/khusmann/interlacer.
@Manual{, title = {interlacer: Read Tabular Data With Interlaced Values And Missing Reasons}, author = {Kyle Husmann}, year = {2024}, - note = {R package version 0.4.0, https://kylehusmann.com/interlacer}, + note = {R package version 0.4.1, https://kylehusmann.com/interlacer}, url = {https://github.com/khusmann/interlacer}, }