From b44b8f23b4f2a9e8dd09caf2e1fb5f1f7123c875 Mon Sep 17 00:00:00 2001 From: shelby Date: Wed, 26 Jan 2022 14:10:00 -0700 Subject: [PATCH 01/26] change to one sentence per line --- vignettes/readr.Rmd | 59 +++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 16 deletions(-) diff --git a/vignettes/readr.Rmd b/vignettes/readr.Rmd index 91911789..803adfcd 100644 --- a/vignettes/readr.Rmd +++ b/vignettes/readr.Rmd @@ -12,7 +12,9 @@ library(readr) knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` -The key problem that readr solves is __parsing__ a flat file into a tibble. Parsing is the process of taking a text file and turning it into a rectangular tibble where each column is the appropriate part. Parsing takes place in three basic stages: +The key problem that readr solves is __parsing__ a flat file into a tibble. +Parsing is the process of taking a text file and turning it into a rectangular tibble where each column is the appropriate part. +Parsing takes place in three basic stages: 1. The flat file is parsed into a rectangular matrix of strings. @@ -22,7 +24,8 @@ The key problem that readr solves is __parsing__ a flat file into a tibble. Pars 1. Each column of strings is parsed into a vector of a more specific type. -It's easiest to learn how this works in the opposite order Below, you'll learn how the: +It's easiest to learn how this works in the opposite order. +Below, you'll learn how the: 1. __Vector parsers__ turn a character vector in to a more specific type. @@ -38,7 +41,9 @@ Each `parse_*()` is coupled with a `col_*()` function, which will be used in the ## Vector parsers -It's easiest to learn the vector parses using `parse_` functions. These all take a character vector and some options. They return a new vector the same length as the old, along with an attribute describing any problems. +It's easiest to learn the vector parses using `parse_` functions. +These all take a character vector and some options. +They return a new vector the same length as the old, along with an attribute describing any problems. ### Atomic vectors @@ -50,11 +55,14 @@ parse_double(c("1.56", "2.34", "3.56")) parse_logical(c("true", "false")) ``` -By default, readr expects `.` as the decimal mark and `,` as the grouping mark. You can override this default using `locale()`, as described in `vignette("locales")`. +By default, readr expects `.` as the decimal mark and `,` as the grouping mark. +You can override this default using `locale()`, as described in `vignette("locales")`. ### Flexible numeric parser -`parse_integer()` and `parse_double()` are strict: the input string must be a single number with no leading or trailing characters. `parse_number()` is more flexible: it ignores non-numeric prefixes and suffixes, and knows how to deal with grouping marks. This makes it suitable for reading currencies and percentages: +`parse_integer()` and `parse_double()` are strict: the input string must be a single number with no leading or trailing characters. +`parse_number()` is more flexible: it ignores non-numeric prefixes and suffixes, and knows how to deal with grouping marks. +This makes it suitable for reading currencies and percentages: ```{r} parse_number(c("0%", "10%", "150%")) @@ -75,7 +83,8 @@ parse_date("2010-10-01") parse_time("1:00pm") ``` -Each function takes a `format` argument which describes the format of the string. If not specified, it uses a default value: +Each function takes a `format` argument which describes the format of the string. +If not specified, it uses a default value: * `parse_datetime()` recognises [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) @@ -100,7 +109,8 @@ parse_datetime("02/02/15", "%m/%d/%y") ### Factors -When reading a column that has a known set of values, you can read directly into a factor. `parse_factor()` will generate a warning if a value is not in the supplied levels. +When reading a column that has a known set of values, you can read directly into a factor. +`parse_factor()` will generate a warning if a value is not in the supplied levels. ```{r} parse_factor(c("a", "b", "a"), levels = c("a", "b", "c")) @@ -109,7 +119,9 @@ parse_factor(c("a", "b", "d"), levels = c("a", "b", "c")) ## Column specification -It would be tedious if you had to specify the type of every column when reading a file. Instead readr, uses some heuristics to guess the type of each column. You can access these results yourself using `guess_parser()`: +It would be tedious if you had to specify the type of every column when reading a file. +Instead readr, uses some heuristics to guess the type of each column. +You can access these results yourself using `guess_parser()`: ```{r} guess_parser(c("a", "b", "c")) @@ -118,14 +130,17 @@ guess_parser(c("1,000", "2,000", "3,000")) guess_parser(c("2001/10/10")) ``` -The guessing policies are described in the documentation for the individual functions. Guesses are fairly strict. For example, we don't guess that currencies are numbers, even though we can parse them: +The guessing policies are described in the documentation for the individual functions. +Guesses are fairly strict. +For example, we don't guess that currencies are numbers, even though we can parse them: ```{r} guess_parser("$1,234") parse_number("$1,234") ``` -There are two parsers that will never be guessed: `col_skip()` and `col_factor()`. You will always need to supply these explicitly. +There are two parsers that will never be guessed: `col_skip()` and `col_factor()`. +You will always need to supply these explicitly. You can see the specification that readr would generate for a column file by using `spec_csv()`, `spec_tsv()` and so on: @@ -143,7 +158,10 @@ cols_condense(mtcars_spec) ``` -By default readr only looks at the first 1000 rows. This keeps file parsing speedy, but can generate incorrect guesses. For example, in `challenge.csv` the column types change in row 1001, so readr guesses the wrong types. One way to resolve the problem is to increase the number of rows: +By default readr only looks at the first 1000 rows. +This keeps file parsing speedy, but can generate incorrect guesses. +For example, in `challenge.csv` the column types change in row 1001, so readr guesses the wrong types. +One way to resolve the problem is to increase the number of rows: ```{r} x <- spec_csv(readr_example("challenge.csv"), guess_max = 1001) @@ -166,7 +184,9 @@ Each of these functions firsts calls `spec_xxx()` (as described above), and then df1 <- read_csv(readr_example("challenge.csv")) ``` -The rectangular parsing functions almost always succeed; they'll only fail if the format is severely messed up. Instead, readr will generate a data frame of problems. The first few will be printed out, and you can access them all with `problems()`: +The rectangular parsing functions almost always succeed; they'll only fail if the format is severely messed up. +Instead, readr will generate a data frame of problems. +The first few will be printed out, and you can access them all with `problems()`: ```{r} problems(df1) @@ -199,7 +219,8 @@ spec(df1) spec(df2) ``` -(This also allows you to access the full column specification if you're reading a very wide file. By default, readr will only print the specification of the first 20 columns.) +(This also allows you to access the full column specification if you're reading a very wide file. +By default, readr will only print the specification of the first 20 columns.) If you want to manually specify the column types, you can start by copying and pasting this code, and then tweaking it fix the parsing problems. @@ -213,7 +234,10 @@ df3 <- read_csv( ) ``` -In general, it's good practice to supply an explicit column specification. It is more work, but it ensures that you get warnings if the data changes in unexpected ways. To be really strict, you can use `stop_for_problems(df3)`. This will throw an error if there are any parsing problems, forcing you to fix those problems before proceeding with the analysis. +In general, it's good practice to supply an explicit column specification. +It is more work, but it ensures that you get warnings if the data changes in unexpected ways. +To be really strict, you can use `stop_for_problems(df3)`. +This will throw an error if there are any parsing problems, forcing you to fix those problems before proceeding with the analysis. ### Available column specifications @@ -231,7 +255,8 @@ The available specifications are: (with string abbreviations in brackets) * `col_skip()` [_, -], don't import this column. * `col_guess()` [?], parse using the "best" type based on the input. -Use the `col_types` argument to override the default choices. There are two ways to use it: +Use the `col_types` argument to override the default choices. +There are two ways to use it: * With a string: `"dc__d"`: read first column as double, second as character, skip the next two and read the last column as a double. (There's no way to @@ -290,6 +315,8 @@ read_csv("iris.csv", col_types = cols_only( ### Output -The output of all these functions is a tibble. Note that characters are never automatically converted to factors (i.e. no more `stringsAsFactors = FALSE`) and column names are left as is, not munged into valid R identifiers (i.e. there is no `check.names = TRUE`). Row names are never set. +The output of all these functions is a tibble. +Note that characters are never automatically converted to factors (i.e. no more `stringsAsFactors = FALSE`) and column names are left as is, not munged into valid R identifiers (i.e. there is no `check.names = TRUE`). +Row names are never set. Attributes store the column specification (`spec()`) and any parsing problems (`problems()`). From 02dd2f892bb2569c119ec5c04d621eab1894ac31 Mon Sep 17 00:00:00 2001 From: shelby Date: Thu, 27 Jan 2022 12:38:30 -0700 Subject: [PATCH 02/26] first big reorg --- vignettes/column-types.Rmd | 131 +++++++++++++++++++++++++ vignettes/readr.Rmd | 189 ++----------------------------------- 2 files changed, 138 insertions(+), 182 deletions(-) diff --git a/vignettes/column-types.Rmd b/vignettes/column-types.Rmd index 04581755..084f2efa 100644 --- a/vignettes/column-types.Rmd +++ b/vignettes/column-types.Rmd @@ -14,6 +14,18 @@ knitr::opts_chunk$set( ) ``` +The key problem that readr solves is __parsing__ a flat file into a tibble. +Parsing is the process of taking a text file and turning it into a rectangular tibble where each column is the appropriate part. +Parsing takes place in three basic stages: + +1. The flat file is parsed into a rectangular matrix of + strings. + +1. The type of each column is determined. + +1. Each column of strings is parsed into a vector of a + more specific type. + readr will guess column types from the data if the user does not specify the types. The `guess_max` parameter controls how many rows of the input file are used to form these guesses. Ideally, the column types would be completely obvious from the first non-header row and we could use `guess_max = 1`. @@ -162,3 +174,122 @@ Clean up the temporary tricky csv file. ```{r} file.remove(tfile) ``` + +## Vector parsers + +It's easiest to learn the vector parsers using `parse_` functions. +These all take a character vector and some options. +They return a new vector the same length as the old, along with an attribute describing any problems. + +### Atomic vectors + +`parse_logical()`, `parse_integer()`, `parse_double()`, and `parse_character()` are straightforward parsers that produce the corresponding atomic vector. + +```{r} +parse_integer(c("1", "2", "3")) +parse_double(c("1.56", "2.34", "3.56")) +parse_logical(c("true", "false")) +``` + +By default, readr expects `.` as the decimal mark and `,` as the grouping mark. +You can override this default using `locale()`, as described in `vignette("locales")`. + +### Flexible numeric parser + +`parse_integer()` and `parse_double()` are strict: the input string must be a single number with no leading or trailing characters. +`parse_number()` is more flexible: it ignores non-numeric prefixes and suffixes, and knows how to deal with grouping marks. +This makes it suitable for reading currencies and percentages: + +```{r} +parse_number(c("0%", "10%", "150%")) +parse_number(c("$1,234.5", "$12.45")) +``` + +### Date/times + +readr supports three types of date/time data: + +* dates: number of days since 1970-01-01. +* times: number of seconds since midnight. +* datetimes: number of seconds since midnight 1970-01-01. + +```{r} +parse_datetime("2010-10-01 21:45") +parse_date("2010-10-01") +parse_time("1:00pm") +``` + +Each function takes a `format` argument which describes the format of the string. +If not specified, it uses a default value: + +* `parse_datetime()` recognises + [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) + datetimes. + +* `parse_date()` uses the `date_format` specified by + the `locale()`. The default value is `%AD` which uses + an automatic date parser that recognises dates of the + format `Y-m-d` or `Y/m/d`. + +* `parse_time()` uses the `time_format` specified by + the `locale()`. The default value is `%At` which uses + an automatic time parser that recognises times of the + form `H:M` optionally followed by seconds and am/pm. + +In most cases, you will need to supply a `format`, as documented in `parse_datetime()`: + +```{r} +parse_datetime("1 January, 2010", "%d %B, %Y") +parse_datetime("02/02/15", "%m/%d/%y") +``` + +### Factors + +When reading a column that has a known set of values, you can read directly into a factor. +`parse_factor()` will generate a warning if a value is not in the supplied levels. + +```{r} +parse_factor(c("a", "b", "a"), levels = c("a", "b", "c")) +parse_factor(c("a", "b", "d"), levels = c("a", "b", "c")) +``` + + +## Column specification + +readr uses some heuristics to guess the type of each column which can be accessed using `guess_parser()`: + +```{r} +guess_parser(c("a", "b", "c")) +guess_parser(c("1", "2", "3")) +guess_parser(c("1,000", "2,000", "3,000")) +guess_parser(c("2001/10/10")) +``` + +The guessing policies are described in the documentation for the individual functions. +Guesses are fairly strict. +For example, we don't guess that currencies are numbers, even though we can parse them: + +```{r} +guess_parser("$1,234") +parse_number("$1,234") +``` + +There are two parsers that will never be guessed: `col_skip()` and `col_factor()`. +You will always need to supply these explicitly. + +You can see the specification that readr would generate for a column file by using `spec_csv()`, `spec_tsv()` and so on: + +```{r} +x <- spec_csv(readr_example("challenge.csv")) +``` + +For bigger files, you can often make the specification simpler by changing the default column type using `cols_condense()` + +```{r} +mtcars_spec <- spec_csv(readr_example("mtcars.csv")) +mtcars_spec + +cols_condense(mtcars_spec) +``` + + diff --git a/vignettes/readr.Rmd b/vignettes/readr.Rmd index 803adfcd..531f0d8b 100644 --- a/vignettes/readr.Rmd +++ b/vignettes/readr.Rmd @@ -8,177 +8,13 @@ vignette: > --- ```{r, include = FALSE} -library(readr) knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` -The key problem that readr solves is __parsing__ a flat file into a tibble. -Parsing is the process of taking a text file and turning it into a rectangular tibble where each column is the appropriate part. -Parsing takes place in three basic stages: - -1. The flat file is parsed into a rectangular matrix of - strings. - -1. The type of each column is determined. - -1. Each column of strings is parsed into a vector of a - more specific type. - -It's easiest to learn how this works in the opposite order. -Below, you'll learn how the: - -1. __Vector parsers__ turn a character vector in to a - more specific type. - -1. __Column specification__ describes the type of each - column and the strategy readr uses to guess types so - you don't need to supply them all. - -1. __Rectangular parsers__ turn a flat file into a - matrix of rows and columns. - -Each `parse_*()` is coupled with a `col_*()` function, which will be used in the process of parsing a complete tibble. - -## Vector parsers - -It's easiest to learn the vector parses using `parse_` functions. -These all take a character vector and some options. -They return a new vector the same length as the old, along with an attribute describing any problems. - -### Atomic vectors - -`parse_logical()`, `parse_integer()`, `parse_double()`, and `parse_character()` are straightforward parsers that produce the corresponding atomic vector. - ```{r} -parse_integer(c("1", "2", "3")) -parse_double(c("1.56", "2.34", "3.56")) -parse_logical(c("true", "false")) -``` - -By default, readr expects `.` as the decimal mark and `,` as the grouping mark. -You can override this default using `locale()`, as described in `vignette("locales")`. - -### Flexible numeric parser - -`parse_integer()` and `parse_double()` are strict: the input string must be a single number with no leading or trailing characters. -`parse_number()` is more flexible: it ignores non-numeric prefixes and suffixes, and knows how to deal with grouping marks. -This makes it suitable for reading currencies and percentages: - -```{r} -parse_number(c("0%", "10%", "150%")) -parse_number(c("$1,234.5", "$12.45")) -``` - -### Date/times - -readr supports three types of date/time data: - -* dates: number of days since 1970-01-01. -* times: number of seconds since midnight. -* datetimes: number of seconds since midnight 1970-01-01. - -```{r} -parse_datetime("2010-10-01 21:45") -parse_date("2010-10-01") -parse_time("1:00pm") -``` - -Each function takes a `format` argument which describes the format of the string. -If not specified, it uses a default value: - -* `parse_datetime()` recognises - [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) - datetimes. - -* `parse_date()` uses the `date_format` specified by - the `locale()`. The default value is `%AD` which uses - an automatic date parser that recognises dates of the - format `Y-m-d` or `Y/m/d`. - -* `parse_time()` uses the `time_format` specified by - the `locale()`. The default value is `%At` which uses - an automatic time parser that recognises times of the - form `H:M` optionally followed by seconds and am/pm. - -In most cases, you will need to supply a `format`, as documented in `parse_datetime()`: - -```{r} -parse_datetime("1 January, 2010", "%d %B, %Y") -parse_datetime("02/02/15", "%m/%d/%y") -``` - -### Factors - -When reading a column that has a known set of values, you can read directly into a factor. -`parse_factor()` will generate a warning if a value is not in the supplied levels. - -```{r} -parse_factor(c("a", "b", "a"), levels = c("a", "b", "c")) -parse_factor(c("a", "b", "d"), levels = c("a", "b", "c")) -``` - -## Column specification - -It would be tedious if you had to specify the type of every column when reading a file. -Instead readr, uses some heuristics to guess the type of each column. -You can access these results yourself using `guess_parser()`: - -```{r} -guess_parser(c("a", "b", "c")) -guess_parser(c("1", "2", "3")) -guess_parser(c("1,000", "2,000", "3,000")) -guess_parser(c("2001/10/10")) -``` - -The guessing policies are described in the documentation for the individual functions. -Guesses are fairly strict. -For example, we don't guess that currencies are numbers, even though we can parse them: - -```{r} -guess_parser("$1,234") -parse_number("$1,234") -``` - -There are two parsers that will never be guessed: `col_skip()` and `col_factor()`. -You will always need to supply these explicitly. - -You can see the specification that readr would generate for a column file by using `spec_csv()`, `spec_tsv()` and so on: - -```{r} -x <- spec_csv(readr_example("challenge.csv")) -``` - -For bigger files, you can often make the specification simpler by changing the default column type using `cols_condense()` - -```{r} -mtcars_spec <- spec_csv(readr_example("mtcars.csv")) -mtcars_spec - -cols_condense(mtcars_spec) -``` - - -By default readr only looks at the first 1000 rows. -This keeps file parsing speedy, but can generate incorrect guesses. -For example, in `challenge.csv` the column types change in row 1001, so readr guesses the wrong types. -One way to resolve the problem is to increase the number of rows: - -```{r} -x <- spec_csv(readr_example("challenge.csv"), guess_max = 1001) +library(readr) ``` -Another way is to manually specify the `col_type`, as described below. - -## Rectangular parsers - -readr comes with five parsers for rectangular file formats: - -* `read_csv()` and `read_csv2()` for csv files -* `read_tsv()` for tabs separated files -* `read_fwf()` for fixed-width files -* `read_log()` for web log files - -Each of these functions firsts calls `spec_xxx()` (as described above), and then parses the file according to that column specification: ```{r} df1 <- read_csv(readr_example("challenge.csv")) @@ -202,16 +38,6 @@ Another approach is to manually supply the column specification. ### Overriding the defaults -In the previous examples, you may have noticed that readr printed the column specification that it used to parse the file: - -```{r} -#> Parsed with column specification: -#> cols( -#> x = col_integer(), -#> y = col_character() -#> ) -``` - You can also access it after the fact using `spec()`: ```{r} @@ -219,8 +45,7 @@ spec(df1) spec(df2) ``` -(This also allows you to access the full column specification if you're reading a very wide file. -By default, readr will only print the specification of the first 20 columns.) +This also allows you to access the full column specification. If you want to manually specify the column types, you can start by copying and pasting this code, and then tweaking it fix the parsing problems. @@ -264,7 +89,7 @@ There are two ways to use it: * With a (named) list of col objects: - ```r + ```{r} read_csv("iris.csv", col_types = list( Sepal.Length = col_double(), Sepal.Width = col_double(), @@ -276,7 +101,7 @@ There are two ways to use it: Or, with their abbreviations: - ```r + ```{r} read_csv("iris.csv", col_types = list( Sepal.Length = "d", Sepal.Width = "d", @@ -289,7 +114,7 @@ There are two ways to use it: Any omitted columns will be parsed automatically, so the previous call will lead to the same result as: -```r +```{r} read_csv("iris.csv", col_types = list( Species = col_factor(c("setosa", "versicolor", "virginica"))) ) @@ -298,7 +123,7 @@ read_csv("iris.csv", col_types = list( You can also set a default type that will be used instead of relying on the automatic detection for columns you don't specify: -```r +```{r} read_csv("iris.csv", col_types = list( Species = col_factor(c("setosa", "versicolor", "virginica")), .default = col_double()) @@ -307,7 +132,7 @@ read_csv("iris.csv", col_types = list( If you only want to read specified columns, use `cols_only()`: -```r +```{r} read_csv("iris.csv", col_types = cols_only( Species = col_factor(c("setosa", "versicolor", "virginica"))) ) From ac90055a3e30b61e375ed5ac810e8fc9a5283061 Mon Sep 17 00:00:00 2001 From: shelby Date: Mon, 31 Jan 2022 15:24:21 -0700 Subject: [PATCH 03/26] make outline for new vignette --- vignettes/readr.Rmd | 138 ++++++++++++++++++++------------------------ 1 file changed, 63 insertions(+), 75 deletions(-) diff --git a/vignettes/readr.Rmd b/vignettes/readr.Rmd index 531f0d8b..76a71c4f 100644 --- a/vignettes/readr.Rmd +++ b/vignettes/readr.Rmd @@ -11,60 +11,88 @@ vignette: > knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` +Importing and exporting data to and from R is an important operation to master. +Here, we will review how to use readr's suite of functions to do just that. + +First, let's load the readr package. + ```{r} library(readr) ``` +## Data importing + +To import data into Rstudio, there are a number of different readr functions to import different types of data files found in the wild: + +* `read_csv()`: comma separated values (CSV) files +* `read_tsv()`: tab separated values (TSV) files +* `read_delim()`: general delimited files (including CSV and TSV) +* `read_fwf()`: fixed width files +* `read_table()`: tabular files where columns are separated by white-space. +* `read_log()`: web log files + +For delimited files, `read_delim()` will work for both csv and tsv files. There are certain arguments in `read_delim()` that are so commonly used together, they are offered as defaults. These include `read_csv()` and `read_tsv()`. + +For R users who need `read_csv()` to use ',' as the decimal point and ';' as a field separator, `read_csv2()` offers these as default arguments. + +## Optional Arguments + +It's often the case that our data needs some help to importing into R. +The readr functions come with several optional arguments to make data importing easier. +Because these arguments are conserved across functions, we can demonstrate them using `read_csv()`. + +### skip + ```{r} -df1 <- read_csv(readr_example("challenge.csv")) +filepath <- readr_example("skip-lines.csv") +writeLines(read_lines(filepath)) +read_csv(filepath, skip = 5) ``` -The rectangular parsing functions almost always succeed; they'll only fail if the format is severely messed up. -Instead, readr will generate a data frame of problems. -The first few will be printed out, and you can access them all with `problems()`: +### na ```{r} -problems(df1) ``` -You've already seen one way of handling bad guesses: increasing the number of rows used to guess the type of each column. +### reading in multiple files ```{r} -df2 <- read_csv(readr_example("challenge.csv"), guess_max = 1001) ``` -Another approach is to manually supply the column specification. +### id -### Overriding the defaults +```{r} +``` -You can also access it after the fact using `spec()`: +### trim white space ```{r} -spec(df1) -spec(df2) ``` -This also allows you to access the full column specification. +### lazy + +```{r} +``` -If you want to manually specify the column types, you can start by copying and pasting this code, and then tweaking it fix the parsing problems. + +### n_max ```{r} -df3 <- read_csv( - readr_example("challenge.csv"), - col_types = list( - x = col_double(), - y = col_date(format = "") - ) -) ``` -In general, it's good practice to supply an explicit column specification. -It is more work, but it ensures that you get warnings if the data changes in unexpected ways. -To be really strict, you can use `stop_for_problems(df3)`. -This will throw an error if there are any parsing problems, forcing you to fix those problems before proceeding with the analysis. +### quote -### Available column specifications +```{r} +``` + + + +### col_types + +In general, it's good practice to supply an explicit column specification. +Sometimes, you don't know what column specification to use, which is why readr packages will guess it for you, if not specified. +But as your analysis matures, providing readr with column specification will ensures that you get warnings if the data changes in unexpected ways. The available specifications are: (with string abbreviations in brackets) @@ -80,68 +108,28 @@ The available specifications are: (with string abbreviations in brackets) * `col_skip()` [_, -], don't import this column. * `col_guess()` [?], parse using the "best" type based on the input. -Use the `col_types` argument to override the default choices. -There are two ways to use it: +To provide readr functions with column specification, use the `col_types` argument. -* With a string: `"dc__d"`: read first column as double, second as character, - skip the next two and read the last column as a double. (There's no way to - use this form with types that take additional parameters.) - -* With a (named) list of col objects: ```{r} - read_csv("iris.csv", col_types = list( - Sepal.Length = col_double(), - Sepal.Width = col_double(), - Petal.Length = col_double(), - Petal.Width = col_double(), - Species = col_factor(c("setosa", "versicolor", "virginica")) - )) - ``` - - Or, with their abbreviations: - - ```{r} - read_csv("iris.csv", col_types = list( - Sepal.Length = "d", - Sepal.Width = "d", - Petal.Length = "d", - Petal.Width = "d", - Species = col_factor(c("setosa", "versicolor", "virginica")) - )) + ``` -Any omitted columns will be parsed automatically, so the previous call -will lead to the same result as: +## Troubleshooting ```{r} -read_csv("iris.csv", col_types = list( - Species = col_factor(c("setosa", "versicolor", "virginica"))) -) +df1 <- read_csv(readr_example("")) ``` -You can also set a default type that will be used instead of -relying on the automatic detection for columns you don't specify: +If the column type guessing fails, readr will generate a data frame of problems. +The first few will be printed out, and you can access them all with `problems()`: ```{r} -read_csv("iris.csv", col_types = list( - Species = col_factor(c("setosa", "versicolor", "virginica")), - .default = col_double()) -) +problems(df1) ``` -If you only want to read specified columns, use `cols_only()`: + ```{r} -read_csv("iris.csv", col_types = cols_only( - Species = col_factor(c("setosa", "versicolor", "virginica"))) -) +read_lines(readr_example(""), skip = 404, n_max = 1) ``` - -### Output - -The output of all these functions is a tibble. -Note that characters are never automatically converted to factors (i.e. no more `stringsAsFactors = FALSE`) and column names are left as is, not munged into valid R identifiers (i.e. there is no `check.names = TRUE`). -Row names are never set. - -Attributes store the column specification (`spec()`) and any parsing problems (`problems()`). From c33dfc71975a5b9bf4b75f44e9ca958b775c6942 Mon Sep 17 00:00:00 2001 From: shelby Date: Mon, 31 Jan 2022 15:24:47 -0700 Subject: [PATCH 04/26] add example file for skip --- inst/extdata/skip-lines.csv | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 inst/extdata/skip-lines.csv diff --git a/inst/extdata/skip-lines.csv b/inst/extdata/skip-lines.csv new file mode 100644 index 00000000..b8f940fc --- /dev/null +++ b/inst/extdata/skip-lines.csv @@ -0,0 +1,11 @@ +x,y +1, +2, +3, +4, +5, +1,34 +2,36 +3,35 +4,33 +5,134 From 451237ce7b7acee33e5bda2bd6b1b5266c2a5af5 Mon Sep 17 00:00:00 2001 From: shelby Date: Mon, 31 Jan 2022 16:33:53 -0700 Subject: [PATCH 05/26] add example for interpreting nas --- inst/extdata/interpret-nas.csv | 11 +++++++++++ vignettes/readr.Rmd | 3 +++ 2 files changed, 14 insertions(+) create mode 100644 inst/extdata/interpret-nas.csv diff --git a/inst/extdata/interpret-nas.csv b/inst/extdata/interpret-nas.csv new file mode 100644 index 00000000..6604d2b2 --- /dev/null +++ b/inst/extdata/interpret-nas.csv @@ -0,0 +1,11 @@ +x,y +1,45 +2,- +3,66 +4,30 +5,- +1,34 +2,36 +3,35 +4,33 +5,134 diff --git a/vignettes/readr.Rmd b/vignettes/readr.Rmd index 76a71c4f..31f54302 100644 --- a/vignettes/readr.Rmd +++ b/vignettes/readr.Rmd @@ -53,6 +53,9 @@ read_csv(filepath, skip = 5) ### na ```{r} +filepath <- readr_example("interpret-nas.csv") +writeLines(read_lines(filepath)) +read_csv(filepath, na = "-") ``` ### reading in multiple files From 3b9215786eedb48d5cf5b0e2a4c60e999f80ca31 Mon Sep 17 00:00:00 2001 From: shelby Date: Tue, 1 Feb 2022 11:41:23 -0700 Subject: [PATCH 06/26] add more gunk to skip lines file --- inst/extdata/skip-lines.csv | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/inst/extdata/skip-lines.csv b/inst/extdata/skip-lines.csv index b8f940fc..39050df4 100644 --- a/inst/extdata/skip-lines.csv +++ b/inst/extdata/skip-lines.csv @@ -1,11 +1,11 @@ +Apex,01/03/2021 +96-well, +, +, +, x,y -1, -2, -3, -4, -5, -1,34 -2,36 -3,35 -4,33 -5,134 +A1,34 +A2,36 +A3,35 +A4,33 +A5,134 From c3eeb3f8608833b401723b5ccfe6fd3b3f7492f3 Mon Sep 17 00:00:00 2001 From: shelby Date: Tue, 1 Feb 2022 11:41:48 -0700 Subject: [PATCH 07/26] add examples for lazy --- vignettes/readr.Rmd | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/vignettes/readr.Rmd b/vignettes/readr.Rmd index 31f54302..a3b6852b 100644 --- a/vignettes/readr.Rmd +++ b/vignettes/readr.Rmd @@ -43,7 +43,6 @@ Because these arguments are conserved across functions, we can demonstrate them ### skip - ```{r} filepath <- readr_example("skip-lines.csv") writeLines(read_lines(filepath)) @@ -71,26 +70,39 @@ read_csv(filepath, na = "-") ### trim white space ```{r} +trim <- tibble::tibble(x = c("high ", " medium", "low", "medium low"), y = c(10, 10, 10, 15)) +tfile <- tempfile("trim-whitespace_example-", fileext = ".csv") +write_csv(trim, tfile) +writeLines(read_lines(tfile)) +``` + +```{r} +read_csv(tfile, trim_ws = TRUE) ``` ### lazy ```{r} +chicken_data <- read_csv(readr_example("chickens.csv")) +chicken_data <- chicken_data %>% dplyr::filter(sex == "hen") +chicken_data ``` - ### n_max ```{r} +read_csv(readr_example("mtcars.csv"), n_max = 5) +read_csv(readr_example("mtcars.csv")) ``` ### quote ```{r} +filepath <- readr_example("chickens.csv") +writeLines(read_lines(filepath)) +read_csv(readr_example("chickens.csv"), quote = "\"") ``` - - ### col_types In general, it's good practice to supply an explicit column specification. @@ -114,9 +126,8 @@ The available specifications are: (with string abbreviations in brackets) To provide readr functions with column specification, use the `col_types` argument. - ```{r} - - ``` +```{r} +``` ## Troubleshooting From ff8bf4ff107e91582d1922d0b9571085064f4359 Mon Sep 17 00:00:00 2001 From: shelby Date: Tue, 1 Feb 2022 13:42:38 -0700 Subject: [PATCH 08/26] Add parsing problem file --- inst/extdata/problems.csv | 3001 +++++++++++++++++++++++++++++++++++++ vignettes/readr.Rmd | 12 +- 2 files changed, 3010 insertions(+), 3 deletions(-) create mode 100644 inst/extdata/problems.csv diff --git a/inst/extdata/problems.csv b/inst/extdata/problems.csv new file mode 100644 index 00000000..c8690dfd --- /dev/null +++ b/inst/extdata/problems.csv @@ -0,0 +1,3001 @@ +Duration,Value +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +7 minutes,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 +2.99,56 diff --git a/vignettes/readr.Rmd b/vignettes/readr.Rmd index a3b6852b..de144adc 100644 --- a/vignettes/readr.Rmd +++ b/vignettes/readr.Rmd @@ -100,7 +100,7 @@ read_csv(readr_example("mtcars.csv")) ```{r} filepath <- readr_example("chickens.csv") writeLines(read_lines(filepath)) -read_csv(readr_example("chickens.csv"), quote = "\"") +read_csv(filepath, quote = "\"") ``` ### col_types @@ -127,12 +127,18 @@ To provide readr functions with column specification, use the `col_types` argume ```{r} +read_csv(readr_example("chickens.csv"), + col_types = cols( + chicken = col_character(), + sex = col_character(), + eggs_laid = col_integer(), + motto = col_character())) ``` ## Troubleshooting ```{r} -df1 <- read_csv(readr_example("")) +df1 <- read_csv(readr_example("problems.csv")) ``` If the column type guessing fails, readr will generate a data frame of problems. @@ -145,5 +151,5 @@ problems(df1) ```{r} -read_lines(readr_example(""), skip = 404, n_max = 1) +read_lines(readr_example("problems.csv"), skip = 300, n_max = 1) ``` From 5c290252de55647ced6be42c420a17aee52c80f3 Mon Sep 17 00:00:00 2001 From: shelby Date: Tue, 1 Feb 2022 14:06:52 -0700 Subject: [PATCH 09/26] add `locale()` section --- vignettes/readr.Rmd | 102 +++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 48 deletions(-) diff --git a/vignettes/readr.Rmd b/vignettes/readr.Rmd index de144adc..695c39bd 100644 --- a/vignettes/readr.Rmd +++ b/vignettes/readr.Rmd @@ -33,7 +33,10 @@ To import data into Rstudio, there are a number of different readr functions to For delimited files, `read_delim()` will work for both csv and tsv files. There are certain arguments in `read_delim()` that are so commonly used together, they are offered as defaults. These include `read_csv()` and `read_tsv()`. -For R users who need `read_csv()` to use ',' as the decimal point and ';' as a field separator, `read_csv2()` offers these as default arguments. +For R users who need `read_csv()` to use ',' as the decimal point and ';' as a field separator, `read_csv2()` offers these as default arguments. +This delimiter is most common in European countries. +Because R is US-centric, the default options for most functions are also US-centric. However, you can specify your location with the `locale()` function which will make encoding data easier. +We will go into more detail about how `locale()` works later on and how it can help make your code more portable. ## Optional Arguments @@ -41,12 +44,35 @@ It's often the case that our data needs some help to importing into R. The readr functions come with several optional arguments to make data importing easier. Because these arguments are conserved across functions, we can demonstrate them using `read_csv()`. -### skip +### col_types + +In general, it's good practice to supply an explicit column specification. +Sometimes, you don't know what column specification to use, which is why readr packages will guess it for you, if not specified. +But as your analysis matures, providing readr with column specification will ensures that you get warnings if the data changes in unexpected ways. + +The available specifications are: (with string abbreviations in brackets) + +* `col_logical()` [l], containing only `T`, `F`, `TRUE` or `FALSE`. +* `col_integer()` [i], integers. +* `col_double()` [d], doubles. +* `col_character()` [c], everything else. +* `col_factor(levels, ordered)` [f], a fixed set of values. +* `col_date(format = "")` [D]: with the locale's `date_format`. +* `col_time(format = "")` [t]: with the locale's `time_format`. +* `col_datetime(format = "")` [T]: ISO8601 date times +* `col_number()` [n], numbers containing the `grouping_mark` +* `col_skip()` [_, -], don't import this column. +* `col_guess()` [?], parse using the "best" type based on the input. + +To provide readr functions with column specification, use the `col_types` argument. ```{r} -filepath <- readr_example("skip-lines.csv") -writeLines(read_lines(filepath)) -read_csv(filepath, skip = 5) +read_csv(readr_example("chickens.csv"), + col_types = cols( + chicken = col_character(), + sex = col_character(), + eggs_laid = col_integer(), + motto = col_character())) ``` ### na @@ -57,16 +83,27 @@ writeLines(read_lines(filepath)) read_csv(filepath, na = "-") ``` -### reading in multiple files +### skip + +```{r} +filepath <- readr_example("skip-lines.csv") +writeLines(read_lines(filepath)) +read_csv(filepath, skip = 5) +``` + +### n_max ```{r} +read_csv(readr_example("mtcars.csv"), n_max = 5) +read_csv(readr_example("mtcars.csv")) ``` -### id +### locale ```{r} ``` + ### trim white space ```{r} @@ -80,19 +117,22 @@ writeLines(read_lines(tfile)) read_csv(tfile, trim_ws = TRUE) ``` -### lazy +### reading in multiple files ```{r} -chicken_data <- read_csv(readr_example("chickens.csv")) -chicken_data <- chicken_data %>% dplyr::filter(sex == "hen") -chicken_data ``` -### n_max +### id ```{r} -read_csv(readr_example("mtcars.csv"), n_max = 5) -read_csv(readr_example("mtcars.csv")) +``` + +### lazy + +```{r} +chicken_data <- read_csv(readr_example("chickens.csv")) +chicken_data <- chicken_data %>% dplyr::filter(sex == "hen") +chicken_data ``` ### quote @@ -103,38 +143,6 @@ writeLines(read_lines(filepath)) read_csv(filepath, quote = "\"") ``` -### col_types - -In general, it's good practice to supply an explicit column specification. -Sometimes, you don't know what column specification to use, which is why readr packages will guess it for you, if not specified. -But as your analysis matures, providing readr with column specification will ensures that you get warnings if the data changes in unexpected ways. - -The available specifications are: (with string abbreviations in brackets) - -* `col_logical()` [l], containing only `T`, `F`, `TRUE` or `FALSE`. -* `col_integer()` [i], integers. -* `col_double()` [d], doubles. -* `col_character()` [c], everything else. -* `col_factor(levels, ordered)` [f], a fixed set of values. -* `col_date(format = "")` [D]: with the locale's `date_format`. -* `col_time(format = "")` [t]: with the locale's `time_format`. -* `col_datetime(format = "")` [T]: ISO8601 date times -* `col_number()` [n], numbers containing the `grouping_mark` -* `col_skip()` [_, -], don't import this column. -* `col_guess()` [?], parse using the "best" type based on the input. - -To provide readr functions with column specification, use the `col_types` argument. - - -```{r} -read_csv(readr_example("chickens.csv"), - col_types = cols( - chicken = col_character(), - sex = col_character(), - eggs_laid = col_integer(), - motto = col_character())) -``` - ## Troubleshooting ```{r} @@ -148,8 +156,6 @@ The first few will be printed out, and you can access them all with `problems()` problems(df1) ``` - - ```{r} read_lines(readr_example("problems.csv"), skip = 300, n_max = 1) ``` From 798aed837c0e080e4ea8621967185ea48871829a Mon Sep 17 00:00:00 2001 From: shelby Date: Wed, 2 Feb 2022 10:40:11 -0700 Subject: [PATCH 10/26] use googlesheets4 example datasets --- inst/extdata/deaths-other.csv | 19 +++++++++++++++++++ inst/extdata/deaths.csv | 19 +++++++++++++++++++ inst/extdata/skip-lines.csv | 11 ----------- vignettes/readr.Rmd | 31 ++++++++++++++++++++++++------- 4 files changed, 62 insertions(+), 18 deletions(-) create mode 100644 inst/extdata/deaths-other.csv create mode 100644 inst/extdata/deaths.csv delete mode 100644 inst/extdata/skip-lines.csv diff --git a/inst/extdata/deaths-other.csv b/inst/extdata/deaths-other.csv new file mode 100644 index 00000000..93ae1802 --- /dev/null +++ b/inst/extdata/deaths-other.csv @@ -0,0 +1,19 @@ +For the sake,,,,, +,of consistency,,,in the,"data layout," +which is really,,,,a,"beautiful thing," +I will,keep making notes,,,,up here. +Name,Profession,Age,Has kids,Date of birth,Date of death +Vera Rubin,scientist,88,TRUE,7/23/1928,12/25/2016 +Mohamed Ali,athlete,74,TRUE,1/17/1942,6/3/2016 +Morley Safer,journalist,84,TRUE,11/8/1931,5/19/2016 +Fidel Castro,politician,90,TRUE,8/13/1926,11/25/2016 +Antonin Scalia,lawyer,79,TRUE,3/11/1936,2/13/2016 +Jo Cox,politician,41,TRUE,6/22/1974,6/16/2016 +Janet Reno,lawyer,78,FALSE,7/21/1938,11/7/2016 +Gwen Ifill,journalist,61,FALSE,9/29/1955,11/14/2016 +John Glenn,astronaut,95,TRUE,7/28/1921,12/8/2016 +Pat Summit,coach,64,TRUE,6/14/1952,6/28/2016 +This,,,,, +,"has been really fun, but",,,, +we're signing,,,,, +,,off,,now!, \ No newline at end of file diff --git a/inst/extdata/deaths.csv b/inst/extdata/deaths.csv new file mode 100644 index 00000000..a9884c10 --- /dev/null +++ b/inst/extdata/deaths.csv @@ -0,0 +1,19 @@ +Lots of people,,,,, +simply cannot resist writing,,,,,some notes +at,the,top,,of,their spreadsheets +or,merging,,,,cells +Name,Profession,Age,Has kids,Date of birth,Date of death +David Bowie,musician,69,TRUE,1/8/1947,1/10/2016 +Carrie Fisher,actor,60,TRUE,10/21/1956,12/27/2016 +Chuck Berry,musician,90,TRUE,10/18/1926,3/18/2017 +Bill Paxton,actor,61,TRUE,5/17/1955,2/25/2017 +Prince,musician,57,TRUE,6/7/1958,4/21/2016 +Alan Rickman,actor,69,FALSE,2/21/1946,1/14/2016 +Florence Henderson,actor,82,TRUE,2/14/1934,11/24/2016 +Harper Lee,author,89,FALSE,4/28/1926,2/19/2016 +Zsa Zsa Gábor,actor,99,TRUE,2/6/1917,12/18/2016 +George Michael,musician,53,FALSE,6/25/1963,12/25/2016 +Some,,,,, +,also like to write stuff,,,, +,,at the,"bottom,",, +,,,,,too! \ No newline at end of file diff --git a/inst/extdata/skip-lines.csv b/inst/extdata/skip-lines.csv deleted file mode 100644 index 39050df4..00000000 --- a/inst/extdata/skip-lines.csv +++ /dev/null @@ -1,11 +0,0 @@ -Apex,01/03/2021 -96-well, -, -, -, -x,y -A1,34 -A2,36 -A3,35 -A4,33 -A5,134 diff --git a/vignettes/readr.Rmd b/vignettes/readr.Rmd index 695c39bd..7c9df09c 100644 --- a/vignettes/readr.Rmd +++ b/vignettes/readr.Rmd @@ -40,7 +40,6 @@ We will go into more detail about how `locale()` works later on and how it can h ## Optional Arguments -It's often the case that our data needs some help to importing into R. The readr functions come with several optional arguments to make data importing easier. Because these arguments are conserved across functions, we can demonstrate them using `read_csv()`. @@ -86,28 +85,32 @@ read_csv(filepath, na = "-") ### skip ```{r} -filepath <- readr_example("skip-lines.csv") +filepath <- readr_example("deaths.csv") writeLines(read_lines(filepath)) -read_csv(filepath, skip = 5) +read_csv(filepath, skip = 4) ``` ### n_max ```{r} -read_csv(readr_example("mtcars.csv"), n_max = 5) -read_csv(readr_example("mtcars.csv")) +read_csv(filepath, skip = 4, n_max = 10) ``` ### locale ```{r} + ``` ### trim white space ```{r} -trim <- tibble::tibble(x = c("high ", " medium", "low", "medium low"), y = c(10, 10, 10, 15)) +trim <- tibble::tibble(x = c("high ", + " medium", + "low", + "medium low"), + y = c(10, 10, 10, 15)) tfile <- tempfile("trim-whitespace_example-", fileext = ".csv") write_csv(trim, tfile) writeLines(read_lines(tfile)) @@ -117,14 +120,28 @@ writeLines(read_lines(tfile)) read_csv(tfile, trim_ws = TRUE) ``` +```{r} +file.remove(tfile) +``` + ### reading in multiple files ```{r} -``` +read_csv(c(readr_example("deaths.csv"), + readr_example("deaths-other.csv")), + skip = 4, + n_max = 10) +``` ### id ```{r} +read_csv(c(readr_example("deaths.csv"), + readr_example("deaths-other.csv")), + skip = 4, + n_max = 10, + id = "filename") + ``` ### lazy From ba2f590a08dd4fd76ea79c1201219cacd84dd954 Mon Sep 17 00:00:00 2001 From: shelby Date: Wed, 2 Feb 2022 10:40:25 -0700 Subject: [PATCH 11/26] reorg column-types.Rmd --- vignettes/column-types.Rmd | 239 +++++++++++++++++++------------------ 1 file changed, 121 insertions(+), 118 deletions(-) diff --git a/vignettes/column-types.Rmd b/vignettes/column-types.Rmd index 084f2efa..59deef3d 100644 --- a/vignettes/column-types.Rmd +++ b/vignettes/column-types.Rmd @@ -14,6 +14,8 @@ knitr::opts_chunk$set( ) ``` + + The key problem that readr solves is __parsing__ a flat file into a tibble. Parsing is the process of taking a text file and turning it into a rectangular tibble where each column is the appropriate part. Parsing takes place in three basic stages: @@ -32,6 +34,125 @@ Ideally, the column types would be completely obvious from the first non-header That would be very efficient! But the situation is rarely so clear-cut. +## Vector parsers + +It's easiest to learn the vector parsers using `parse_` functions. +These all take a character vector and some options. +They return a new vector the same length as the old, along with an attribute describing any problems. + +### Atomic vectors + +`parse_logical()`, `parse_integer()`, `parse_double()`, and `parse_character()` are straightforward parsers that produce the corresponding atomic vector. + +```{r} +parse_integer(c("1", "2", "3")) +parse_double(c("1.56", "2.34", "3.56")) +parse_logical(c("true", "false")) +``` + +By default, readr expects `.` as the decimal mark and `,` as the grouping mark. +You can override this default using `locale()`, as described in `vignette("locales")`. + +### Flexible numeric parser + +`parse_integer()` and `parse_double()` are strict: the input string must be a single number with no leading or trailing characters. +`parse_number()` is more flexible: it ignores non-numeric prefixes and suffixes, and knows how to deal with grouping marks. +This makes it suitable for reading currencies and percentages: + +```{r} +parse_number(c("0%", "10%", "150%")) +parse_number(c("$1,234.5", "$12.45")) +``` + +### Date/times + +readr supports three types of date/time data: + +* dates: number of days since 1970-01-01. +* times: number of seconds since midnight. +* datetimes: number of seconds since midnight 1970-01-01. + +```{r} +parse_datetime("2010-10-01 21:45") +parse_date("2010-10-01") +parse_time("1:00pm") +``` + +Each function takes a `format` argument which describes the format of the string. +If not specified, it uses a default value: + +* `parse_datetime()` recognises + [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) + datetimes. + +* `parse_date()` uses the `date_format` specified by + the `locale()`. The default value is `%AD` which uses + an automatic date parser that recognises dates of the + format `Y-m-d` or `Y/m/d`. + +* `parse_time()` uses the `time_format` specified by + the `locale()`. The default value is `%At` which uses + an automatic time parser that recognises times of the + form `H:M` optionally followed by seconds and am/pm. + +In most cases, you will need to supply a `format`, as documented in `parse_datetime()`: + +```{r} +parse_datetime("1 January, 2010", "%d %B, %Y") +parse_datetime("02/02/15", "%m/%d/%y") +``` + +### Factors + +When reading a column that has a known set of values, you can read directly into a factor. +`parse_factor()` will generate a warning if a value is not in the supplied levels. + +```{r} +parse_factor(c("a", "b", "a"), levels = c("a", "b", "c")) +parse_factor(c("a", "b", "d"), levels = c("a", "b", "c")) +``` + + +## Column specification + +readr uses some heuristics to guess the type of each column which can be accessed using `guess_parser()`: + +```{r} +guess_parser(c("a", "b", "c")) +guess_parser(c("1", "2", "3")) +guess_parser(c("1,000", "2,000", "3,000")) +guess_parser(c("2001/10/10")) +``` + +The guessing policies are described in the documentation for the individual functions. +Guesses are fairly strict. +For example, we don't guess that currencies are numbers, even though we can parse them: + +```{r} +guess_parser("$1,234") +parse_number("$1,234") +``` + +There are two parsers that will never be guessed: `col_skip()` and `col_factor()`. +You will always need to supply these explicitly. + +You can see the specification that readr would generate for a column file by using `spec_csv()`, `spec_tsv()` and so on: + +```{r} +x <- spec_csv(readr_example("challenge.csv")) +``` + +For bigger files, you can often make the specification simpler by changing the default column type using `cols_condense()` + +```{r} +mtcars_spec <- spec_csv(readr_example("mtcars.csv")) +mtcars_spec + +cols_condense(mtcars_spec) +``` + +## Column type guessing + By default, readr consults 1000 rows when type-guessing, i.e. `guess_max = 1000`. Note that readr never consults rows that won't be part of the import, so the actual default is `guess_max = min(1000, n_max)`. @@ -175,121 +296,3 @@ Clean up the temporary tricky csv file. file.remove(tfile) ``` -## Vector parsers - -It's easiest to learn the vector parsers using `parse_` functions. -These all take a character vector and some options. -They return a new vector the same length as the old, along with an attribute describing any problems. - -### Atomic vectors - -`parse_logical()`, `parse_integer()`, `parse_double()`, and `parse_character()` are straightforward parsers that produce the corresponding atomic vector. - -```{r} -parse_integer(c("1", "2", "3")) -parse_double(c("1.56", "2.34", "3.56")) -parse_logical(c("true", "false")) -``` - -By default, readr expects `.` as the decimal mark and `,` as the grouping mark. -You can override this default using `locale()`, as described in `vignette("locales")`. - -### Flexible numeric parser - -`parse_integer()` and `parse_double()` are strict: the input string must be a single number with no leading or trailing characters. -`parse_number()` is more flexible: it ignores non-numeric prefixes and suffixes, and knows how to deal with grouping marks. -This makes it suitable for reading currencies and percentages: - -```{r} -parse_number(c("0%", "10%", "150%")) -parse_number(c("$1,234.5", "$12.45")) -``` - -### Date/times - -readr supports three types of date/time data: - -* dates: number of days since 1970-01-01. -* times: number of seconds since midnight. -* datetimes: number of seconds since midnight 1970-01-01. - -```{r} -parse_datetime("2010-10-01 21:45") -parse_date("2010-10-01") -parse_time("1:00pm") -``` - -Each function takes a `format` argument which describes the format of the string. -If not specified, it uses a default value: - -* `parse_datetime()` recognises - [ISO8601](https://en.wikipedia.org/wiki/ISO_8601) - datetimes. - -* `parse_date()` uses the `date_format` specified by - the `locale()`. The default value is `%AD` which uses - an automatic date parser that recognises dates of the - format `Y-m-d` or `Y/m/d`. - -* `parse_time()` uses the `time_format` specified by - the `locale()`. The default value is `%At` which uses - an automatic time parser that recognises times of the - form `H:M` optionally followed by seconds and am/pm. - -In most cases, you will need to supply a `format`, as documented in `parse_datetime()`: - -```{r} -parse_datetime("1 January, 2010", "%d %B, %Y") -parse_datetime("02/02/15", "%m/%d/%y") -``` - -### Factors - -When reading a column that has a known set of values, you can read directly into a factor. -`parse_factor()` will generate a warning if a value is not in the supplied levels. - -```{r} -parse_factor(c("a", "b", "a"), levels = c("a", "b", "c")) -parse_factor(c("a", "b", "d"), levels = c("a", "b", "c")) -``` - - -## Column specification - -readr uses some heuristics to guess the type of each column which can be accessed using `guess_parser()`: - -```{r} -guess_parser(c("a", "b", "c")) -guess_parser(c("1", "2", "3")) -guess_parser(c("1,000", "2,000", "3,000")) -guess_parser(c("2001/10/10")) -``` - -The guessing policies are described in the documentation for the individual functions. -Guesses are fairly strict. -For example, we don't guess that currencies are numbers, even though we can parse them: - -```{r} -guess_parser("$1,234") -parse_number("$1,234") -``` - -There are two parsers that will never be guessed: `col_skip()` and `col_factor()`. -You will always need to supply these explicitly. - -You can see the specification that readr would generate for a column file by using `spec_csv()`, `spec_tsv()` and so on: - -```{r} -x <- spec_csv(readr_example("challenge.csv")) -``` - -For bigger files, you can often make the specification simpler by changing the default column type using `cols_condense()` - -```{r} -mtcars_spec <- spec_csv(readr_example("mtcars.csv")) -mtcars_spec - -cols_condense(mtcars_spec) -``` - - From a4bcca73c4dcc419b1563b6ea6702b9e7d46089d Mon Sep 17 00:00:00 2001 From: shelby Date: Wed, 2 Feb 2022 11:29:47 -0700 Subject: [PATCH 12/26] add `locale()` example --- inst/extdata/norway.csv | 25 +++++++++++++++++++++++++ vignettes/readr.Rmd | 5 +++-- 2 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 inst/extdata/norway.csv diff --git a/inst/extdata/norway.csv b/inst/extdata/norway.csv new file mode 100644 index 00000000..9322feb5 --- /dev/null +++ b/inst/extdata/norway.csv @@ -0,0 +1,25 @@ +date,value +1 januar 2022,"1,23" +15 januar 2022,"3,21" +30 januar 2022,"4,55" +1 februar 2022,"10,67" +15 februar 2022,"333,23" +28 februar 2022,"343,33" +1 mars 2022,"11,32" +15 mars 2022,"3,98" +30 mars 2022,"44,12" +1 april 2022,"1,22" +15 april 2022,"9,04" +30 April 2022,"45,05" +1 mai 2022,"788,02" +15 mai 2022,"65,21" +30 mai 2022,"67,55" +1 juni 2022,"127.897,23" +15 juni 2022,"322.222,21" +30 juni 2022,"240,55" +1 juli 2022,"170,23" +15 juli 2022,"3,09" +30 juli 2022,"42,06" +1 august 2022,"89,43" +15 august 2022,"7,21" +30 august 2022,"1,55" diff --git a/vignettes/readr.Rmd b/vignettes/readr.Rmd index 7c9df09c..ae506e76 100644 --- a/vignettes/readr.Rmd +++ b/vignettes/readr.Rmd @@ -99,10 +99,11 @@ read_csv(filepath, skip = 4, n_max = 10) ### locale ```{r} - +filepath <- readr_example("norway.csv") +writeLines(read_lines(filepath)) +read_csv(filepath, locale = locale("nb", date_format = "%d %B %Y", decimal_mark = ",")) ``` - ### trim white space ```{r} From 95ff042b6d6df6da038249c5e6a0143e2cf38e71 Mon Sep 17 00:00:00 2001 From: shelby Date: Wed, 2 Feb 2022 11:47:54 -0700 Subject: [PATCH 13/26] make `problems()` example more slightly interesting --- inst/extdata/problems.csv | 2 +- vignettes/readr.Rmd | 11 ++++++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/inst/extdata/problems.csv b/inst/extdata/problems.csv index c8690dfd..ddfa8dc2 100644 --- a/inst/extdata/problems.csv +++ b/inst/extdata/problems.csv @@ -2976,7 +2976,7 @@ Duration,Value 2.99,56 2.99,56 2.99,56 -2.99,56 +5-9 minutes,56 2.99,56 2.99,56 2.99,56 diff --git a/vignettes/readr.Rmd b/vignettes/readr.Rmd index ae506e76..ae011a64 100644 --- a/vignettes/readr.Rmd +++ b/vignettes/readr.Rmd @@ -175,5 +175,14 @@ problems(df1) ``` ```{r} -read_lines(readr_example("problems.csv"), skip = 300, n_max = 1) +writeLines(read_lines(readr_example("problems.csv"), skip = 300, n_max = 1)) ``` + +```{r} +read_csv(readr_example("problems.csv"), + col_types = cols(Duration = col_character(), + Value = col_integer())) +``` + + + From d0c25c278fa1d6ab613a09af4f8952f2fc9817e5 Mon Sep 17 00:00:00 2001 From: shelby Date: Wed, 2 Feb 2022 12:06:36 -0700 Subject: [PATCH 14/26] review before creating PR --- vignettes/column-types.Rmd | 14 ++++++-------- vignettes/readr.Rmd | 3 ++- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/vignettes/column-types.Rmd b/vignettes/column-types.Rmd index 59deef3d..0c2b4000 100644 --- a/vignettes/column-types.Rmd +++ b/vignettes/column-types.Rmd @@ -14,8 +14,6 @@ knitr::opts_chunk$set( ) ``` - - The key problem that readr solves is __parsing__ a flat file into a tibble. Parsing is the process of taking a text file and turning it into a rectangular tibble where each column is the appropriate part. Parsing takes place in three basic stages: @@ -28,12 +26,6 @@ Parsing takes place in three basic stages: 1. Each column of strings is parsed into a vector of a more specific type. -readr will guess column types from the data if the user does not specify the types. -The `guess_max` parameter controls how many rows of the input file are used to form these guesses. -Ideally, the column types would be completely obvious from the first non-header row and we could use `guess_max = 1`. -That would be very efficient! -But the situation is rarely so clear-cut. - ## Vector parsers It's easiest to learn the vector parsers using `parse_` functions. @@ -153,6 +145,12 @@ cols_condense(mtcars_spec) ## Column type guessing +readr will guess column types from the data if the user does not specify the types. +The `guess_max` parameter controls how many rows of the input file are used to form these guesses. +Ideally, the column types would be completely obvious from the first non-header row and we could use `guess_max = 1`. +That would be very efficient! +But the situation is rarely so clear-cut. + By default, readr consults 1000 rows when type-guessing, i.e. `guess_max = 1000`. Note that readr never consults rows that won't be part of the import, so the actual default is `guess_max = min(1000, n_max)`. diff --git a/vignettes/readr.Rmd b/vignettes/readr.Rmd index ae011a64..87b74a15 100644 --- a/vignettes/readr.Rmd +++ b/vignettes/readr.Rmd @@ -134,6 +134,7 @@ read_csv(c(readr_example("deaths.csv"), n_max = 10) ``` + ### id ```{r} @@ -148,7 +149,7 @@ read_csv(c(readr_example("deaths.csv"), ### lazy ```{r} -chicken_data <- read_csv(readr_example("chickens.csv")) +chicken_data <- read_csv(readr_example("chickens.csv"), lazy = TRUE) chicken_data <- chicken_data %>% dplyr::filter(sex == "hen") chicken_data ``` From f8bdbc19998ae06701f0d91950bda3675235077f Mon Sep 17 00:00:00 2001 From: shelby Date: Thu, 3 Feb 2022 12:07:38 -0700 Subject: [PATCH 15/26] fix my errors --- vignettes/column-types.Rmd | 6 ++++++ vignettes/readr.Rmd | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/vignettes/column-types.Rmd b/vignettes/column-types.Rmd index 0c2b4000..8d32b68b 100644 --- a/vignettes/column-types.Rmd +++ b/vignettes/column-types.Rmd @@ -32,6 +32,12 @@ It's easiest to learn the vector parsers using `parse_` functions. These all take a character vector and some options. They return a new vector the same length as the old, along with an attribute describing any problems. +First, let's load the readr library + +```{r} +library(readr) +``` + ### Atomic vectors `parse_logical()`, `parse_integer()`, `parse_double()`, and `parse_character()` are straightforward parsers that produce the corresponding atomic vector. diff --git a/vignettes/readr.Rmd b/vignettes/readr.Rmd index 87b74a15..c7013759 100644 --- a/vignettes/readr.Rmd +++ b/vignettes/readr.Rmd @@ -150,7 +150,7 @@ read_csv(c(readr_example("deaths.csv"), ```{r} chicken_data <- read_csv(readr_example("chickens.csv"), lazy = TRUE) -chicken_data <- chicken_data %>% dplyr::filter(sex == "hen") +chicken_data <- dplyr::filter(chicken_data, sex == "hen") chicken_data ``` From 8f9771cd528d41747ebd4df5032d8137eb3371a4 Mon Sep 17 00:00:00 2001 From: shelby Date: Thu, 3 Feb 2022 14:31:27 -0700 Subject: [PATCH 16/26] And fix another one --- vignettes/readr.Rmd | 1 - 1 file changed, 1 deletion(-) diff --git a/vignettes/readr.Rmd b/vignettes/readr.Rmd index c7013759..50bd6e70 100644 --- a/vignettes/readr.Rmd +++ b/vignettes/readr.Rmd @@ -150,7 +150,6 @@ read_csv(c(readr_example("deaths.csv"), ```{r} chicken_data <- read_csv(readr_example("chickens.csv"), lazy = TRUE) -chicken_data <- dplyr::filter(chicken_data, sex == "hen") chicken_data ``` From cd523e151487a285bcfec29c58392c6649d7b8da Mon Sep 17 00:00:00 2001 From: shelby Date: Tue, 15 Feb 2022 09:56:05 -0700 Subject: [PATCH 17/26] incorporate feedback --- vignettes/readr.Rmd | 189 +++++++++++++++++++++++++++++++++----------- 1 file changed, 142 insertions(+), 47 deletions(-) diff --git a/vignettes/readr.Rmd b/vignettes/readr.Rmd index 50bd6e70..d6f30311 100644 --- a/vignettes/readr.Rmd +++ b/vignettes/readr.Rmd @@ -14,15 +14,22 @@ knitr::opts_chunk$set(collapse = TRUE, comment = "#>") Importing and exporting data to and from R is an important operation to master. Here, we will review how to use readr's suite of functions to do just that. -First, let's load the readr package. +We can load the readr package individually with: ```{r} library(readr) ``` +Alternatively, because readr is a core tidyverse package we can also load it, along with the rest of the tidyverse package with: + + +```{r, eval = FALSE} +library(tidyverse) +``` + ## Data importing -To import data into Rstudio, there are a number of different readr functions to import different types of data files found in the wild: +To import data into R, there are a number of different readr functions to import different types of data files found in the wild: * `read_csv()`: comma separated values (CSV) files * `read_tsv()`: tab separated values (TSV) files @@ -31,23 +38,28 @@ To import data into Rstudio, there are a number of different readr functions to * `read_table()`: tabular files where columns are separated by white-space. * `read_log()`: web log files -For delimited files, `read_delim()` will work for both csv and tsv files. There are certain arguments in `read_delim()` that are so commonly used together, they are offered as defaults. These include `read_csv()` and `read_tsv()`. +For delimited files, `read_delim()` will work for both csv and tsv files. +There are certain arguments in `read_delim()` that are so commonly used together, they are offered as defaults. +These include `read_csv()` and `read_tsv()`. -For R users who need `read_csv()` to use ',' as the decimal point and ';' as a field separator, `read_csv2()` offers these as default arguments. +For R users who need `read_delim()` to use ',' as the decimal point and ';' as a field separator, `read_csv2()` offers these as default arguments. This delimiter is most common in European countries. -Because R is US-centric, the default options for most functions are also US-centric. However, you can specify your location with the `locale()` function which will make encoding data easier. +Because R is US-centric, the default options for most functions are also US-centric. +However, you can specify your location with the `locale()` function which will make encoding data easier. We will go into more detail about how `locale()` works later on and how it can help make your code more portable. ## Optional Arguments The readr functions come with several optional arguments to make data importing easier. +Using these optional arguments at import are a good idea because they can decrease the work needed to wrangle your data after import. + Because these arguments are conserved across functions, we can demonstrate them using `read_csv()`. ### col_types In general, it's good practice to supply an explicit column specification. Sometimes, you don't know what column specification to use, which is why readr packages will guess it for you, if not specified. -But as your analysis matures, providing readr with column specification will ensures that you get warnings if the data changes in unexpected ways. +But as your analysis matures, providing readr with column specification will ensure that you get warnings if the data changes in unexpected ways. The available specifications are: (with string abbreviations in brackets) @@ -66,12 +78,32 @@ The available specifications are: (with string abbreviations in brackets) To provide readr functions with column specification, use the `col_types` argument. ```{r} -read_csv(readr_example("chickens.csv"), - col_types = cols( - chicken = col_character(), - sex = col_character(), - eggs_laid = col_integer(), - motto = col_character())) +df <- tibble::tibble(x = c("02/10/2022", "02/11/2022", "02/12/2022", "02/13/2022"), y = c("0", "2.5", "1", "0"), z = c("low", "high", "medium", "low")) +my_file <- tempfile("df", fileext = ".csv") +write_csv(df, my_file) +writeLines(read_lines(my_file)) +``` + +```{r} +read_csv(my_file) +``` + +```{r} +read_csv(my_file, na = "", col_types = cols( + x = col_date(format = "%m/%d/%Y") +)) +``` + +```{r} +read_csv(my_file, na = "", col_types = cols( + x = col_date(format = "%m/%d/%Y"), + y = col_double(), + z = col_factor() +)) +``` + +```{r, include = FALSE} +file.remove(my_file) ``` ### na @@ -79,7 +111,10 @@ read_csv(readr_example("chickens.csv"), ```{r} filepath <- readr_example("interpret-nas.csv") writeLines(read_lines(filepath)) -read_csv(filepath, na = "-") +``` + +```{r} +read_csv(filepath, na = "-", show_col_types = FALSE) ``` ### skip @@ -87,38 +122,64 @@ read_csv(filepath, na = "-") ```{r} filepath <- readr_example("deaths.csv") writeLines(read_lines(filepath)) -read_csv(filepath, skip = 4) +``` + +```{r} +read_csv(filepath, skip = 5, show_col_types = FALSE) ``` ### n_max +To control the number of rows to read in we can use `n_max`. +In our previous example, the file contains some rows at the end that we'd like to ignore. +Setting `n_max` allows us to limit the rows read in by `read_csv()`. +When combined with `skip`, `read_csv()` reads in ten rows starting at the fourth row. + +```{r} +filepath <- readr_example("mini_gap_Europe.csv") +writeLines(read_lines(filepath)) +``` + ```{r} -read_csv(filepath, skip = 4, n_max = 10) +read_csv(filepath, n_max = 3, show_col_types = FALSE) ``` ### locale +Understanding the `locale()` option gives you more control over importing data from other countries. +The `locale()` option also includes other information not typically found in `locale()` such as time zones and data encoding. + ```{r} filepath <- readr_example("norway.csv") writeLines(read_lines(filepath)) -read_csv(filepath, locale = locale("nb", date_format = "%d %B %Y", decimal_mark = ",")) +``` + +```{r} +read_csv(filepath, + locale = locale("nb", date_format = "%d %B %Y", decimal_mark = ","), + show_col_types = FALSE +) ``` ### trim white space ```{r} -trim <- tibble::tibble(x = c("high ", - " medium", - "low", - "medium low"), - y = c(10, 10, 10, 15)) +trim <- tibble::tibble( + x = c( + "high ", + " medium", + "low", + "medium low" + ), + y = c(10, 10, 10, 15) +) tfile <- tempfile("trim-whitespace_example-", fileext = ".csv") write_csv(trim, tfile) writeLines(read_lines(tfile)) ``` ```{r} -read_csv(tfile, trim_ws = TRUE) +read_csv(tfile, trim_ws = TRUE, show_col_types = FALSE) ``` ```{r} @@ -128,61 +189,95 @@ file.remove(tfile) ### reading in multiple files ```{r} -read_csv(c(readr_example("deaths.csv"), - readr_example("deaths-other.csv")), - skip = 4, - n_max = 10) - +read_csv(c( + readr_example("mini_gap_Europe.csv"), + readr_example("mini_gap_Oceania.csv") +), show_col_types = FALSE) ``` ### id + + +After importing multiple files into a dataframe, you will probably want to track the file name with the data. +Often times the file path contains important information that you might want to include, like the date of data collection. +You can use the id option to create a new column that holds this information. + + ```{r} -read_csv(c(readr_example("deaths.csv"), - readr_example("deaths-other.csv")), - skip = 4, - n_max = 10, - id = "filename") +mini_gap <- read_csv(c( + readr_example("mini_gap_Europe.csv"), + readr_example("mini_gap_Oceania.csv") +), show_col_types = FALSE, id = "filename") +``` + + +It's common to need to tinker with the filename to extract the real information you want to track. +In our example below, we want just the basename of the filepath. + +```{r} +mini_gap$filename <- basename(mini_gap$filename) +mini_gap +``` +We could also do this with dplyr's `mutate()` function. + +```{r, eval = FALSE} +mini_gap <- mini_gap %>% dplyr::mutate(filename = basename(filename)) ``` + ### lazy + + + + + + + ```{r} -chicken_data <- read_csv(readr_example("chickens.csv"), lazy = TRUE) -chicken_data +read_csv(readr_example("mtcars.csv"), col_select = c("mpg", "disp", "hp", "drat", "wt", "gear")) ``` ### quote ```{r} -filepath <- readr_example("chickens.csv") -writeLines(read_lines(filepath)) -read_csv(filepath, quote = "\"") +read_csv(readr_example("funny_quotes.csv"), + show_col_types = FALSE +) +``` + +```{r} +read_csv(readr_example("funny_quotes.csv"), + show_col_types = FALSE, quote = "\'" +) ``` ## Troubleshooting ```{r} -df1 <- read_csv(readr_example("problems.csv")) +my_nums <- read_csv(readr_example("problem_numbers.csv"), col_types = cols(value = col_integer())) ``` -If the column type guessing fails, readr will generate a data frame of problems. +If the column type guessing causes awkward conversions, readr will generate a data frame of problems. The first few will be printed out, and you can access them all with `problems()`: ```{r} -problems(df1) +problems(my_nums) ``` +Getting the data in front of you can help diagnose any problems + ```{r} -writeLines(read_lines(readr_example("problems.csv"), skip = 300, n_max = 1)) +writeLines(read_lines(readr_example("problem_numbers.csv"), skip = 4, n_max = 3)) ``` ```{r} -read_csv(readr_example("problems.csv"), - col_types = cols(Duration = col_character(), - Value = col_integer())) +read_csv(readr_example("problem_numbers.csv"), + col_types = cols(value = col_double()) +) ``` - - - From f4dd8eb734c52f2167ad0389fe46f895ce30e58b Mon Sep 17 00:00:00 2001 From: shelby Date: Tue, 15 Feb 2022 09:56:36 -0700 Subject: [PATCH 18/26] make solving problems more cathartic --- inst/extdata/problem_numbers.csv | 8 + inst/extdata/problems.csv | 3001 ------------------------------ 2 files changed, 8 insertions(+), 3001 deletions(-) create mode 100644 inst/extdata/problem_numbers.csv delete mode 100644 inst/extdata/problems.csv diff --git a/inst/extdata/problem_numbers.csv b/inst/extdata/problem_numbers.csv new file mode 100644 index 00000000..e371c35d --- /dev/null +++ b/inst/extdata/problem_numbers.csv @@ -0,0 +1,8 @@ +value +1 +2 +3 +4 +5.00 +6 +7 diff --git a/inst/extdata/problems.csv b/inst/extdata/problems.csv deleted file mode 100644 index ddfa8dc2..00000000 --- a/inst/extdata/problems.csv +++ /dev/null @@ -1,3001 +0,0 @@ -Duration,Value -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -7 minutes,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -5-9 minutes,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 -2.99,56 From 4377b9ff5efb1b9dec2a5eb0e54186b550eea868 Mon Sep 17 00:00:00 2001 From: shelby Date: Tue, 15 Feb 2022 09:56:54 -0700 Subject: [PATCH 19/26] better example for reading in multiple files --- inst/extdata/mini_gap_Europe.csv | 6 ++++++ inst/extdata/mini_gap_Oceania.csv | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 inst/extdata/mini_gap_Europe.csv create mode 100644 inst/extdata/mini_gap_Oceania.csv diff --git a/inst/extdata/mini_gap_Europe.csv b/inst/extdata/mini_gap_Europe.csv new file mode 100644 index 00000000..deea2093 --- /dev/null +++ b/inst/extdata/mini_gap_Europe.csv @@ -0,0 +1,6 @@ +country,continent,year,lifeExp,pop,gdpPercap +Albania,Europe,1952,55.23,1282697,1601.056136 +Austria,Europe,1952,66.8,6927772,6137.076492 +Belgium,Europe,1952,68,8730405,8343.105127 +Bosnia and Herzegovina,Europe,1952,53.82,2791000,973.5331948 +Bulgaria,Europe,1952,59.6,7274900,2444.286648 \ No newline at end of file diff --git a/inst/extdata/mini_gap_Oceania.csv b/inst/extdata/mini_gap_Oceania.csv new file mode 100644 index 00000000..96226f37 --- /dev/null +++ b/inst/extdata/mini_gap_Oceania.csv @@ -0,0 +1,6 @@ +country,continent,year,lifeExp,pop,gdpPercap +Australia,Oceania,1952,69.12,8691212,10039.59564 +New Zealand,Oceania,1952,69.39,1994794,10556.57566 +Australia,Oceania,1957,70.33,9712569,10949.64959 +New Zealand,Oceania,1957,70.26,2229407,12247.39532 +Australia,Oceania,1962,70.93,10794968,12217.22686 \ No newline at end of file From 5f907b25097785c04ee28453d34b162d42aff55d Mon Sep 17 00:00:00 2001 From: shelby Date: Tue, 15 Feb 2022 09:57:23 -0700 Subject: [PATCH 20/26] quotes example is now more robust --- inst/extdata/funny_quotes.csv | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 inst/extdata/funny_quotes.csv diff --git a/inst/extdata/funny_quotes.csv b/inst/extdata/funny_quotes.csv new file mode 100644 index 00000000..f71f8160 --- /dev/null +++ b/inst/extdata/funny_quotes.csv @@ -0,0 +1,4 @@ +Size, Cost +'Small', $5.00 +'Medium, Large, Extra Large',$10.00 + From 4273b4825960eb71bf2847a5eba38bebc065f5f1 Mon Sep 17 00:00:00 2001 From: shelby Date: Tue, 15 Feb 2022 09:57:41 -0700 Subject: [PATCH 21/26] make the file smaller --- inst/extdata/interpret-nas.csv | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/inst/extdata/interpret-nas.csv b/inst/extdata/interpret-nas.csv index 6604d2b2..0a0620ff 100644 --- a/inst/extdata/interpret-nas.csv +++ b/inst/extdata/interpret-nas.csv @@ -4,8 +4,4 @@ x,y 3,66 4,30 5,- -1,34 -2,36 -3,35 -4,33 -5,134 + From 8e6255bd569b46a3875a64e177ba23c7b4e1354a Mon Sep 17 00:00:00 2001 From: shelby Date: Tue, 15 Feb 2022 09:58:00 -0700 Subject: [PATCH 22/26] remove trailing junk and add better leading junk --- inst/extdata/deaths.csv | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/inst/extdata/deaths.csv b/inst/extdata/deaths.csv index a9884c10..f2023ae0 100644 --- a/inst/extdata/deaths.csv +++ b/inst/extdata/deaths.csv @@ -1,7 +1,8 @@ -Lots of people,,,,, -simply cannot resist writing,,,,,some notes -at,the,top,,of,their spreadsheets -or,merging,,,,cells +Date:,02/12/2022,,,, +Name:,Sally,Brown,,, +,,,,, +Instrument:,Piano,,,, +,,,,, Name,Profession,Age,Has kids,Date of birth,Date of death David Bowie,musician,69,TRUE,1/8/1947,1/10/2016 Carrie Fisher,actor,60,TRUE,10/21/1956,12/27/2016 @@ -12,8 +13,4 @@ Alan Rickman,actor,69,FALSE,2/21/1946,1/14/2016 Florence Henderson,actor,82,TRUE,2/14/1934,11/24/2016 Harper Lee,author,89,FALSE,4/28/1926,2/19/2016 Zsa Zsa Gábor,actor,99,TRUE,2/6/1917,12/18/2016 -George Michael,musician,53,FALSE,6/25/1963,12/25/2016 -Some,,,,, -,also like to write stuff,,,, -,,at the,"bottom,",, -,,,,,too! \ No newline at end of file +George Michael,musician,53,FALSE,6/25/1963,12/25/2016 From 8101bbe7c53e878b7ac8eb7d90e57a8061264e97 Mon Sep 17 00:00:00 2001 From: shelby Date: Tue, 15 Feb 2022 09:58:10 -0700 Subject: [PATCH 23/26] used a different file for multiple files example --- inst/extdata/deaths-other.csv | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 inst/extdata/deaths-other.csv diff --git a/inst/extdata/deaths-other.csv b/inst/extdata/deaths-other.csv deleted file mode 100644 index 93ae1802..00000000 --- a/inst/extdata/deaths-other.csv +++ /dev/null @@ -1,19 +0,0 @@ -For the sake,,,,, -,of consistency,,,in the,"data layout," -which is really,,,,a,"beautiful thing," -I will,keep making notes,,,,up here. -Name,Profession,Age,Has kids,Date of birth,Date of death -Vera Rubin,scientist,88,TRUE,7/23/1928,12/25/2016 -Mohamed Ali,athlete,74,TRUE,1/17/1942,6/3/2016 -Morley Safer,journalist,84,TRUE,11/8/1931,5/19/2016 -Fidel Castro,politician,90,TRUE,8/13/1926,11/25/2016 -Antonin Scalia,lawyer,79,TRUE,3/11/1936,2/13/2016 -Jo Cox,politician,41,TRUE,6/22/1974,6/16/2016 -Janet Reno,lawyer,78,FALSE,7/21/1938,11/7/2016 -Gwen Ifill,journalist,61,FALSE,9/29/1955,11/14/2016 -John Glenn,astronaut,95,TRUE,7/28/1921,12/8/2016 -Pat Summit,coach,64,TRUE,6/14/1952,6/28/2016 -This,,,,, -,"has been really fun, but",,,, -we're signing,,,,, -,,off,,now!, \ No newline at end of file From 0cf7cb449f08d9491e813af84889b0149b60bded Mon Sep 17 00:00:00 2001 From: shelby Date: Wed, 23 Feb 2022 16:06:43 -0700 Subject: [PATCH 24/26] make true to csv --- inst/extdata/deaths.csv | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/inst/extdata/deaths.csv b/inst/extdata/deaths.csv index f2023ae0..2ca107bb 100644 --- a/inst/extdata/deaths.csv +++ b/inst/extdata/deaths.csv @@ -1,8 +1,5 @@ -Date:,02/12/2022,,,, -Name:,Sally,Brown,,, -,,,,, -Instrument:,Piano,,,, -,,,,, +Date file created:,02/12/2022,,,, +File created by:,Sally,Brown,,, Name,Profession,Age,Has kids,Date of birth,Date of death David Bowie,musician,69,TRUE,1/8/1947,1/10/2016 Carrie Fisher,actor,60,TRUE,10/21/1956,12/27/2016 From 30875ea8010a59223b03d549c848b673f459e82a Mon Sep 17 00:00:00 2001 From: shelby Date: Wed, 23 Feb 2022 16:06:50 -0700 Subject: [PATCH 25/26] reformat --- vignettes/readr.Rmd | 111 +++++++++++++++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 27 deletions(-) diff --git a/vignettes/readr.Rmd b/vignettes/readr.Rmd index d6f30311..2ea12573 100644 --- a/vignettes/readr.Rmd +++ b/vignettes/readr.Rmd @@ -78,7 +78,26 @@ The available specifications are: (with string abbreviations in brackets) To provide readr functions with column specification, use the `col_types` argument. ```{r} -df <- tibble::tibble(x = c("02/10/2022", "02/11/2022", "02/12/2022", "02/13/2022"), y = c("0", "2.5", "1", "0"), z = c("low", "high", "medium", "low")) +df <- tibble::tibble( + x = c( + "02/10/2022", + "02/11/2022", + "02/12/2022", + "02/13/2022" + ), + y = c( + "0", + "2.5", + "1", + "0" + ), + z = c( + "low", + "high", + "medium", + "low" + ) +) my_file <- tempfile("df", fileext = ".csv") write_csv(df, my_file) writeLines(read_lines(my_file)) @@ -89,17 +108,25 @@ read_csv(my_file) ``` ```{r} -read_csv(my_file, na = "", col_types = cols( - x = col_date(format = "%m/%d/%Y") -)) +read_csv( + my_file, + na = "", + col_types = cols( + x = col_date(format = "%m/%d/%Y") + ) +) ``` ```{r} -read_csv(my_file, na = "", col_types = cols( - x = col_date(format = "%m/%d/%Y"), - y = col_double(), - z = col_factor() -)) +read_csv( + my_file, + na = "", + col_types = cols( + x = col_date(format = "%m/%d/%Y"), + y = col_double(), + z = col_factor() + ) +) ``` ```{r, include = FALSE} @@ -120,12 +147,15 @@ read_csv(filepath, na = "-", show_col_types = FALSE) ### skip ```{r} +# make this more indicative of junk in csv files +# Date created: +# Created by: filepath <- readr_example("deaths.csv") writeLines(read_lines(filepath)) ``` ```{r} -read_csv(filepath, skip = 5, show_col_types = FALSE) +read_csv(filepath, skip = 2, show_col_types = FALSE) ``` ### n_max @@ -155,7 +185,8 @@ writeLines(read_lines(filepath)) ``` ```{r} -read_csv(filepath, +read_csv( + filepath, locale = locale("nb", date_format = "%d %B %Y", decimal_mark = ","), show_col_types = FALSE ) @@ -189,10 +220,13 @@ file.remove(tfile) ### reading in multiple files ```{r} -read_csv(c( - readr_example("mini_gap_Europe.csv"), - readr_example("mini_gap_Oceania.csv") -), show_col_types = FALSE) +read_csv( + c( + readr_example("mini_gap_Europe.csv"), + readr_example("mini_gap_Oceania.csv") + ), + show_col_types = FALSE +) ``` ### id @@ -205,10 +239,13 @@ You can use the id option to create a new column that holds this information. ```{r} -mini_gap <- read_csv(c( - readr_example("mini_gap_Europe.csv"), - readr_example("mini_gap_Oceania.csv") -), show_col_types = FALSE, id = "filename") +mini_gap <- read_csv( + c( + readr_example("mini_gap_Europe.csv"), + readr_example("mini_gap_Oceania.csv") + ), + show_col_types = FALSE, id = "filename" +) ``` @@ -223,7 +260,7 @@ mini_gap We could also do this with dplyr's `mutate()` function. ```{r, eval = FALSE} -mini_gap <- mini_gap %>% dplyr::mutate(filename = basename(filename)) +dplyr::mutate(mini_gap, filename = basename(filename)) ``` @@ -240,19 +277,25 @@ https://youtu.be/RA9AjqZXxMU?t=581 ```{r} -read_csv(readr_example("mtcars.csv"), col_select = c("mpg", "disp", "hp", "drat", "wt", "gear")) + +read_csv( + readr_example("mtcars.csv"), + col_select = c("mpg", "disp", "hp", "drat", "wt", "gear") +) ``` ### quote ```{r} -read_csv(readr_example("funny_quotes.csv"), +read_csv( + readr_example("funny_quotes.csv"), show_col_types = FALSE ) ``` ```{r} -read_csv(readr_example("funny_quotes.csv"), +read_csv( + readr_example("funny_quotes.csv"), show_col_types = FALSE, quote = "\'" ) ``` @@ -260,7 +303,12 @@ read_csv(readr_example("funny_quotes.csv"), ## Troubleshooting ```{r} -my_nums <- read_csv(readr_example("problem_numbers.csv"), col_types = cols(value = col_integer())) +my_nums <- read_csv( + readr_example("problem_numbers.csv"), + col_types = cols( + value = col_integer() + ) +) ``` If the column type guessing causes awkward conversions, readr will generate a data frame of problems. @@ -273,11 +321,20 @@ problems(my_nums) Getting the data in front of you can help diagnose any problems ```{r} -writeLines(read_lines(readr_example("problem_numbers.csv"), skip = 4, n_max = 3)) +writeLines( + read_lines( + readr_example("problem_numbers.csv"), + skip = 4, + n_max = 3 + ) +) ``` ```{r} -read_csv(readr_example("problem_numbers.csv"), - col_types = cols(value = col_double()) +read_csv( + readr_example("problem_numbers.csv"), + col_types = cols( + value = col_double() + ) ) ``` From 6bfe0272ac6bbfcfd4dccb07a9206f8b9d4722fe Mon Sep 17 00:00:00 2001 From: shelby Date: Wed, 23 Feb 2022 19:25:26 -0700 Subject: [PATCH 26/26] adding context --- vignettes/readr.Rmd | 85 ++++++++++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 24 deletions(-) diff --git a/vignettes/readr.Rmd b/vignettes/readr.Rmd index 2ea12573..d2fc88c9 100644 --- a/vignettes/readr.Rmd +++ b/vignettes/readr.Rmd @@ -11,7 +11,7 @@ vignette: > knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` -Importing and exporting data to and from R is an important operation to master. +Importing data to R is an important operation to master. Here, we will review how to use readr's suite of functions to do just that. We can load the readr package individually with: @@ -22,7 +22,6 @@ library(readr) Alternatively, because readr is a core tidyverse package we can also load it, along with the rest of the tidyverse package with: - ```{r, eval = FALSE} library(tidyverse) ``` @@ -50,6 +49,7 @@ We will go into more detail about how `locale()` works later on and how it can h ## Optional Arguments +Data in the wild often comes with certain idiosyncrasies that can make data importing and cleaning difficult. The readr functions come with several optional arguments to make data importing easier. Using these optional arguments at import are a good idea because they can decrease the work needed to wrangle your data after import. @@ -58,9 +58,8 @@ Because these arguments are conserved across functions, we can demonstrate them ### col_types In general, it's good practice to supply an explicit column specification. -Sometimes, you don't know what column specification to use, which is why readr packages will guess it for you, if not specified. -But as your analysis matures, providing readr with column specification will ensure that you get warnings if the data changes in unexpected ways. - +If you don't supply readr with a column specification, it will be guessed for you which by nature of guessing, isn't executed perfectly every time. +To make your data importing more robust, supply a full column specification ensures your data is imported the same way each time. The available specifications are: (with string abbreviations in brackets) * `col_logical()` [l], containing only `T`, `F`, `TRUE` or `FALSE`. @@ -75,9 +74,8 @@ The available specifications are: (with string abbreviations in brackets) * `col_skip()` [_, -], don't import this column. * `col_guess()` [?], parse using the "best" type based on the input. -To provide readr functions with column specification, use the `col_types` argument. -```{r} +```{r, include = FALSE} df <- tibble::tibble( x = c( "02/10/2022", @@ -103,10 +101,16 @@ write_csv(df, my_file) writeLines(read_lines(my_file)) ``` +Sometimes, you don't yet know what column specification to use, which is why readr packages will guess it for you, if not specified. + ```{r} read_csv(my_file) ``` +But as your analysis matures, providing readr with column specification will ensure that you get warnings if the data changes in unexpected ways. +To provide readr functions with column specification, use the `col_types` argument. +You can provide a partial column specification while still importing all the data and the other column types will be guessed. + ```{r} read_csv( my_file, @@ -117,6 +121,8 @@ read_csv( ) ``` +Once you know what column specifications you need, you can supply readr with a full column specification. + ```{r} read_csv( my_file, @@ -135,17 +141,24 @@ file.remove(my_file) ### na +Your data might contain values that you'd like to encode as `NA`. + ```{r} filepath <- readr_example("interpret-nas.csv") writeLines(read_lines(filepath)) ``` +Using this argument with one or more strings will set those values to `NA` at import. + ```{r} read_csv(filepath, na = "-", show_col_types = FALSE) ``` ### skip +When importing data, there may be some content at the top of the file that you'd like to ignore. +The file in the following examples has some header information, like when the file was created, that we'd like to ignore. + ```{r} # make this more indicative of junk in csv files # Date created: @@ -154,6 +167,8 @@ filepath <- readr_example("deaths.csv") writeLines(read_lines(filepath)) ``` +Setting the skip argument to skip these rows will import the data cleanly. + ```{r} read_csv(filepath, skip = 2, show_col_types = FALSE) ``` @@ -161,15 +176,14 @@ read_csv(filepath, skip = 2, show_col_types = FALSE) ### n_max To control the number of rows to read in we can use `n_max`. -In our previous example, the file contains some rows at the end that we'd like to ignore. -Setting `n_max` allows us to limit the rows read in by `read_csv()`. -When combined with `skip`, `read_csv()` reads in ten rows starting at the fourth row. ```{r} filepath <- readr_example("mini_gap_Europe.csv") writeLines(read_lines(filepath)) ``` +Setting `n_max` allows us to limit the rows read in by `read_csv()`. + ```{r} read_csv(filepath, n_max = 3, show_col_types = FALSE) ``` @@ -179,11 +193,17 @@ read_csv(filepath, n_max = 3, show_col_types = FALSE) Understanding the `locale()` option gives you more control over importing data from other countries. The `locale()` option also includes other information not typically found in `locale()` such as time zones and data encoding. +Here we want to import some data from Norway. +Not only are the dates written in Norwegian but the integer values are formatted with a comma decimal mark. + + ```{r} filepath <- readr_example("norway.csv") writeLines(read_lines(filepath)) ``` +Specifying the locale and specifying the date format and decimal mark makes this data more portable. + ```{r} read_csv( filepath, @@ -194,6 +214,8 @@ read_csv( ### trim white space +For data that contains extraneous white spaces, setting `trim_ws = TRUE` can clean up your data at import + ```{r} trim <- tibble::tibble( x = c( @@ -209,16 +231,20 @@ write_csv(trim, tfile) writeLines(read_lines(tfile)) ``` +Now, the white spaces before and after the text are gone! + ```{r} read_csv(tfile, trim_ws = TRUE, show_col_types = FALSE) ``` -```{r} +```{r, include = FALSE} file.remove(tfile) ``` ### reading in multiple files +You can supply readr with a vector of filenames to import, rather than having to import them separately. + ```{r} read_csv( c( @@ -233,11 +259,10 @@ read_csv( -After importing multiple files into a dataframe, you will probably want to track the file name with the data. +After importing multiple files, you will probably want to track the file names with the data that came from them. Often times the file path contains important information that you might want to include, like the date of data collection. You can use the id option to create a new column that holds this information. - ```{r} mini_gap <- read_csv( c( @@ -268,24 +293,29 @@ dplyr::mutate(mini_gap, filename = basename(filename)) - - +One of the big improvements that was made with readr edition 2 was lazy reading. +With lazy reading, the data is read on-demand. +Lazy reading is turned off by default so you much turn it on with `lazy = TRUE`. +In this example, only the data that is needed to calculate the mean mpg for a subset of cars, is loaded into R. -```{r} - +```{r, eval = FALSE} +library(dplyr) read_csv( readr_example("mtcars.csv"), - col_select = c("mpg", "disp", "hp", "drat", "wt", "gear") -) + lazy = TRUE +) %>% + filter(hp > 200) %>% + summarise(mean(mpg)) ``` ### quote +For textual data that contains quoted text, specifying the quote type can impact how the data is imported. +First, we try reading in this data without specifying the quote type. +The default is `quote = "/""`, so this doesn't work well. + ```{r} read_csv( readr_example("funny_quotes.csv"), @@ -293,6 +323,8 @@ read_csv( ) ``` +But when we specify the quote type, readr correctly imports our quoted data. + ```{r} read_csv( readr_example("funny_quotes.csv"), @@ -302,6 +334,9 @@ read_csv( ## Troubleshooting +Data importing doesn't always go as planned. +If there are parsing problems, readr will generate a data frame of problems. + ```{r} my_nums <- read_csv( readr_example("problem_numbers.csv"), @@ -311,14 +346,14 @@ my_nums <- read_csv( ) ``` -If the column type guessing causes awkward conversions, readr will generate a data frame of problems. The first few will be printed out, and you can access them all with `problems()`: ```{r} problems(my_nums) ``` -Getting the data in front of you can help diagnose any problems +Getting the data in front of you can help diagnose any problems. +Use `writeLines()` with `read_lines()` and specify the subset of rows you'd like to look at. ```{r} writeLines( @@ -330,6 +365,8 @@ writeLines( ) ``` +We can fix our problem by specifying that we want this column to be a column of doubles rather than integers. + ```{r} read_csv( readr_example("problem_numbers.csv"),