Академический Документы
Профессиональный Документы
Культура Документы
Matt Wiley
Joshua F. Wiley
Advanced R 4 Data Programming and the Cloud: Using PostgreSQL, AWS, and Shiny
iii
Table of Contents
iv
Table of Contents
v
Table of Contents
vi
Table of Contents
Bibliography��������������������������������������������������������������������������������������������������������� 421
Index��������������������������������������������������������������������������������������������������������������������� 425
vii
About the Authors
Matt Wiley leads institutional effectiveness, research,
and assessment at Victoria College, facilitating strategic
and unit planning, data-informed decision making,
and state/regional/federal accountability. As a tenured,
associate professor of mathematics, he won awards in
both mathematics education (California) and student
engagement (Texas). Matt earned degrees in computer
science, business, and pure mathematics from the University
of California and Texas A&M systems.
Outside academia, he coauthors books about the popular R programming language
and was managing partner of a statistical consultancy for almost a decade. He has
programming experience with R, SQL, C++, Ruby, Fortran, and JavaScript.
A programmer, a published author, a mathematician, and a transformational leader,
Matt has always melded his passion for writing with his joy of logical problem solving
and data science. From the boardroom to the classroom, he enjoys finding dynamic ways
to partner with interdisciplinary and diverse teams to make complex ideas and projects
understandable and solvable. Matt enjoys being found online via Twitter @matt math or
http://mattwiley.org/.
ix
About the Authors
x
About the Technical Reviewer
Andrew Moskowitz is an analytics and data science
professional in the entertainment industry focused on
understanding user behavior, marketing attribution, and
efficacy and using advanced data science concepts to address
business problems. He earned his PhD in quantitative
psychology at the University of California, Los Angeles, where
he focused on hypothesis testing and mixed-effects models.
xi
Acknowledgments
The authors would like to thank the vibrant R community for their hard work, their
cleverness, their willingness to create and share, and most importantly their kindness
to new learners. One author remembers first getting into programming (in a different
language than R) and very early on trying to use an early incarnation of search engine
to discover what “rtfm” meant. One of R’s best community features is a willingness to
share and not mistake new learner for someone to be “hazed.” This civility is something to
nurture and cherish.
We would also like to thank Andrew for sticking with us for a second edition and a
bleeding-edge version release of R. Thank you, Andrew.
Last, and not least, we would like to thank our family. You continue to support us
through a lot of late evenings, early mornings, and the times in between. Thank you.
xiii
CHAPTER 1
Programming Basics
As with most languages, becoming a power user requires extra understanding of the
underlying structure or rules. Data science through R is powerful, and this chapter
discusses such programming basics including objects, operators, and functions.
Before we dig too deeply into R, some general principles to follow may well be in
order. First, experimentation is good. It is much more powerful to learn hands-on than it
is simply to read. Download the source files that come with this text, and try new things!
Second, it can help quite a bit to become familiar with the ? function. Simply type
? immediately followed by text in your R console to call up help of some kind—for
example, ?sum. We cover more on functions later, but this is too useful to ignore until
that time. Using your favorite search engine is also wise (such as this search string: R sum
na). While memorizing some things may be helpful, much of programming is gaining
skill with effective search.
Finally, just before we dive into the real reason you bought this book, a word of
caution: this is an applied text. Our goal is to get you up and running as quickly as
possible toward some useful skills. A rigorous treatment of most of these topics—even or
especially the ideas in this chapter—is worthwhile, yet beyond the scope of this book.
1
© Matt Wiley and Joshua F. Wiley 2020
M. Wiley and J. F. Wiley, Advanced R 4 Data Programming and the Cloud,
https://doi.org/10.1007/978-1-4842-5973-3_1
Chapter 1 Programming Basics
R 4.0.0 https://cran.r-project.org/
RStudio 1.3.959 https://rstudio.com/products/rstudio/download/
Windows 10 www.microsoft.com/
Java 14 www.oracle.com/technetwork/java/javase/overview/index.html
Amazon Cloud https://aws.amazon.com/
Ubuntu https://ubuntu.com/download
options(
width = 70,
stringsAsFactors = FALSE,
digits = 2)
2
Chapter 1 Programming Basics
Logical objects take on just two values: TRUE or FALSE. Computers are binary machines,
and data often may be recorded and modeled in an all-or-nothing world. These logical
values can be helpful, where TRUE has a value of 1 and FALSE has a value of 0.
As a reminder, # (e.g., the pound sign or hashtag) is an indicator of a code comment.
The words that follow the # are not processed by R and are meant to help the reader:
TRUE ## logical
## [1] TRUE
FALSE ## logical
## [1] FALSE
As you may remember from some quickly muttered comments of your college
algebra professor, there are many types of numbers. Whole numbers, which include
zero as well as negative values, are called integers. In set notation, … ,-2, -1, 0, 1, 2, … ,
these numbers are useful for headcounts or other indexes. In R, integers have a capital L
suffix. If decimal numbers are needed, then double numeric objects are in order. These
are the numbers suited for ratio data types. Complex numbers have useful properties as
well and are understood precisely as you might expect, with an i suffix on the imaginary
portion. R is quite friendly in using all of these numbers, and you simply type in the
desired numbers (remember to add the L or i suffix as needed):
42L ## integer
## [1] 42
## [1] 1.5
## [1] 2+3i
Nominal-level data may be stored via the character class and is designated with
quotation marks:
"a" ## character
## [1] "a"
3
Chapter 1 Programming Basics
Of course, numerical data may have missing values. These missing values are of
the type that the rest of the data in that set would be (we discuss data storage shortly).
Nevertheless, it can be helpful to know how to hand-code logical, integer, double,
complex, or character missing values:
NA ## logical
## [1] NA
NA_integer_ ## integer
## [1] NA
## [1] NA
NA_character_ ## character
## [1] NA
NA_complex_ ## complex
## [1] NA
Factors are a special kind of object, not so useful for general programming, but used
a fair amount in statistics. A factor variable indicates that a variable should be treated
discretely. Factors are stored as integers, with labels to indicate the original value:
factor(1:3)
## [1] 1 2 3
## Levels: 1 2 3
## [1] alice bob charlie
## Levels: alice bob charlie
factor(letters[1:3])
## [1] a b c
## Levels: a b c
4
Chapter 1 Programming Basics
We turn now to data structures, which can store objects of the types we have
discussed (and of course more). A vector is a relatively simple data storage object. A
simple way to create a vector is with the concatenate function c():
## vector
c(1, 2, 3)
## [1] 1 2 3
Just as in mathematics, a scalar is a vector of just length 1. Toward the opposite end
of the continuum, a matrix is a vector with dimensions for both rows and columns.
Notice the way the matrix is populated with the numbers 1–6, counting down each
column:
## [1] 1
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
All vectors, be they scalar, vector, or matrix, can have only one data type (e.g., integer,
logical, or complex). If more than one type of data is needed, it may make sense to store
the data in a list. A list is a vector of objects, in which each element of the list may be a
different type. In the following example, we build a list that has character, vector, and
matrix elements:
## vectors and matrices can only have one type of data (e.g., integer,
logical, etc.)
5
Chapter 1 Programming Basics
c(1, 2, 3),
matrix(c(1:6), nrow = 3, ncol = 2)
)
## [[1]]
## [1] "a"
##
## [[2]]
## [1] 1 2 3
##
## [[3]]
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
A particular type of list is the data frame, in which each element of the list is identical
in length (although not necessarily in object type). With the underlying building blocks
of the simpler objects, more complex structures evolve. Take a look at the following
instructive examples with output:
## X1.3 X4.6
## 1 1 4
## 2 2 5
## 3 3 6
6
Chapter 1 Programming Basics
## X1.3 letters.1.3.
## 1 1 a
## 2 2 b
## 3 3 c
Because of their superior computational speed, in this text we primarily use data
table objects in R from the data.table package [9]. Data tables are similar to data frames,
yet are designed to be more memory efficient and faster (mostly due to more underlying
C++ code). Even though we recommend data tables, we show some examples with data
frames as well because when working with R, much historical code includes data frames
and indeed data tables inherit many methods from data frames (notice the last line of
code that follows shows TRUE):
##if not yet installed, run the below line of code if needed.
#install.packages("data.table")
library(data.table)
## data.table 1.12.8 using 6 threads (see ?getDTthreads). Latest news:
r-datatable.com
## V1 V2
## 1: 1 4
## 2: 2 5
## 3: 3 6
is.data.frame(dataTable)
## [1] TRUE
7
Chapter 1 Programming Basics
It is worth mentioning at this stage a little bit about the data structure “wars.”
Historically, the predominant way to structure the types of row/column or tabular data
many researchers use was data frames. As data grew in column width and row length,
this base R structure no longer solved everyone’s needs. Grown out of the same SQL
data control mindset as some of the largest databases, the data.table package/library
is (these days) suited to multiple computer cores and efficient memory operations and
uses more-efficient-than-R languages under the hood. For the largest data sets and for
those who have any background in SQL or other programming languages, data tables
are hugely effective and intuitive. Not all folks first coming to R have a programming
background (and indeed that is a very good thing). A competing data structure, the
tibble, is part of what is called the tidyverse (a portmanteau of tidy and universe). Tibbles,
like data tables, are also data frames at heart, yet they are improved. In the authors’
opinion, while not yet quite as fast as tables, tibbles have a more new-user-friendly
style or language syntax. They’re beloved by a large part of the R community and are an
important part of modern R. In practice, data tables are still faster and can often achieve
tasks your authors find most common in fewer lines of code. Both these newer structures
have their strengths, and both have their place in the R universe (and indeed Chapters 7
and 8 focus on data tables, yet time is given to tibbles in Chapter 9). All the same, this text
will primarily use data tables.
Having explored several types of objects, we turn our attention to ways of
manipulating those objects with operators and functions.
8
Chapter 1 Programming Basics
x <- 5
y = 3
x
## [1] 5
## [1] 3
is.integer(x)
## [1] FALSE
is.double(y)
## [1] TRUE
is.vector(x)
## [1] TRUE
It can help to be able to pronounce and speak these lines of code (and indeed that
idea is at the heart of our preference for <- which reads “is assigned”). The preceding
code might well be read ”the variable x is assigned the integer value 5.” Contrastingly,
while the precise same under-the-hood operation is occurring in the next line with
y, saying ”y equals 3” is perhaps less clear as to whether we are discussing an innate
property of y vs. performing an assignment.
Once an object is assigned, you can access specific object elements by using
brackets. Most computer languages start their indexing at either 0 or 1. R starts indexing
at 1. Also, note you can readily change old assignments with little trouble and no
warning; it is wise to watch names cautiously and comment code carefully:
## [1] "a"
9
Chapter 1 Programming Basics
is.vector(x)
## [1] TRUE
is.vector(x[1])
## [1] TRUE
is.character(x[1])
## [1] TRUE
What do we mean by “watch names carefully”? We called the preceding vector x, and
it was not a very interesting name. Tough to remember x has the first three letters of the
alphabet. Instead, we might choose a better variable name, swapping the tough-to-recall
x with passingLetterGrades. Even better, ours makes sense when spoken variable can
easily be improved later, such as if we wanted to add the sometimes passing letter grade
D or maybe the pass/fail passing grade S:
## [1] "B"
While a vector may take only a single index, more complex structures require more
indices. For the matrix you met earlier, the first index is the row, and the second is for
column position. Notice that after building a matrix and assigning it, there are many
ways to access various combinations of elements. This process of accessing just some of
the elements is sometimes called subsetting:
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
## [1] 4
10
Chapter 1 Programming Basics
## [1] 1 4
## [1] 1 2 3
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [,1] [,2]
## [1,] 1 4
## [2,] 3 6
## [1] 1 2 3
## [,1] [,2]
## [1,] 2 5
## [2,] 3 6
is.vector(x2)
## [1] FALSE
is.matrix(x2)
## [1] TRUE
11
Chapter 1 Programming Basics
Accessing and subsetting lists is perhaps a trifle more complex, yet all the more
essential to learn and master for later techniques. A single index in a single bracket
returns the entire element at that spot (recall that for a list, each element may be a vector
or just a single object). Using double brackets returns the object within that element of
the list—nothing more.
Thus, the following code is, in fact, a vector with the element a inside. Again, using
the data-type-checking functions can be helpful in learning how to interpret various
pieces of code:
y[1]
## [[1]]
## [1] "a"
is.vector(y[1])
## [1] TRUE
is.list(y[1])
## [1] TRUE
is.character(y[1])
## [1] FALSE
## [1] "a"
is.vector(y[[1]])
12
Chapter 1 Programming Basics
## [1] TRUE
is.list(y[[1]])
## [1] FALSE
is.character(y[[1]])
## [1] TRUE
You can, in fact, chain brackets together, so the second element of the list (a vector
with the numbers 1–3) can be accessed, and then, within that vector, the third element
can be accessed:
## [1] 3
Brackets almost always work, depending on the type of object, but there may be
additional ways to access components. Named data frames and lists can use the $
operator. Notice in the following code how the bracket or dollar sign ends up being
equivalent:
x3 <- data.frame(
A = 1:3,
B = 4:6)
y2 <- list(
C = c("a"),
D = c(1, 2, 3))
x3$A
## [1] 1 2 3
y2$C
## [1] "a"
## [1] 1 2 3
13
Chapter 1 Programming Basics
y2[["C"]]
## [1] "a"
Notice that although both data frames and lists are lists, neither is a matrix:
is.list(x3)
## [1] TRUE
is.list(y2)
## [1] TRUE
is.matrix(x3)
## [1] FALSE
is.matrix(y2)
## [1] FALSE
Moreover, despite not being matrices, because of their special nature (i.e., all
elements have equal length), data frames and data tables can be indexed similarly to
matrices:
x3[1, 1]
## [1] 1
x3[1, ]
## A B
## 1 1 4
x3[, 1]
## [1] 1 2 3
Any named object can be indexed by using the names rather than the positional
numbers, provided those names have been set:
x3[1, "A"]
## [1] 1
14
Chapter 1 Programming Basics
x3[, "A"]
## [1] 1 2 3
For data frames, this applies to both column and row names, and these names can
be established after building the matrix:
x3["second", "B"]
## [1] 5
Data tables use a slightly different approach. While we will devote two later chapters
to using data tables, for now, we mention a few facts. Selecting rows works almost
identically, but selecting columns does not require quotes. Additionally, you can select
multiples by name without quotes by using the .() operator. Should you need to use
quotes, the data table can be accessed by using the option with = FALSE such as follows:
x4 <- data.table(
A = 1:3,
B = 4:6)
x4[1, ]
## A B
## 1: 1 4
## [1] 1 2 3
x4[1, A]
## [1] 1
## A B
## 1: 1 4
## 2: 2 5
15
Chapter 1 Programming Basics
## A
## 1: 1
'['(x, 1)
## [1] "a"
## [1] 2
'[['(y, 2)
## [1] 1 2 3
In practice of course, this is almost never used this way. It only needs saying to
understand you can code up your own meaning for any function (we devote a chapter on
writing your own functions). In fact, this is conceptually how data table gets away with
not using quotes for the column names—it changed the way the bracket function works
when is.data.table() returns TRUE.
Although we have been using the is.datatype() function to better illustrate what
an object is, you can do more. Specifically, you can check whether a value is missing an
element by using the is.na() function:
## [1] NA
is.na(NA) ## works
## [1] TRUE
16
Chapter 1 Programming Basics
Of course, the preceding code snippet usually has a vector or matrix element
argument whose populated status is up for debate. Our last (for now) exploratory
function is the inherits() function. It is helpful when no is.class() function exists, which
can occur when specific classes outside the core ones you have seen presented so far are
developed:
inherits(x3, "data.frame")
## [1] TRUE
inherits(x2, "matrix")
## [1] TRUE
You can also force lower types into higher types. This coercion can be helpful but
may have unintended consequences. It can be particularly risky if you have a more
advanced data object being coerced to a lesser type (pay close attention to the attempt to
coerce an integer):
as.integer(3.8)
## [1] 3
as.character(3)
## [1] "3"
as.numeric(3)
## [1] 3
as.complex(3)
## [1] 3+0i
as.factor(3)
## [1] 3
## Levels: 3
as.matrix(3)
## [,1]
## [1,] 3
17
Chapter 1 Programming Basics
as.data.frame(3)
## 3
## 1 3
as.list(3)
## [[1]]
## [1] 3
as.logical("a") ## NA no warning
## [1] NA
## [1] TRUE
## [1] NA
Coercion can be helpful. All the same, it must be used cautiously. Before you move
on from this section, if any of this is new, be sure to experiment with different inputs
than the ones we tried in the preceding example! Experimenting never hurts, and it can
be a powerful way to learn.
Let’s turn our attention now to mathematical and logical operators and functions.
####################MATH################################
###### Comparisons and logicals
4 > 4
## [1] FALSE
18
Chapter 1 Programming Basics
4 >= 4
## [1] TRUE
4 < 4
## [1] FALSE
4 <= 4
## [1] TRUE
4 == 4
## [1] TRUE
4 != 4
## [1] FALSE
It is sensible now to mention that although the preceding code may be helpful,
often numbers differ from one another only slightly—particularly in the programming
environment, which relies on the computer representation of floating-point (irrational)
numbers. Therefore, we often check that things are close within a tolerance:
## [1] TRUE
In symbolic logic, and as well as or are useful comparisons between two objects.
In R, we use & for and vs. | for or. Complex logic tests can be constructed from these
simple structures:
TRUE | FALSE
## [1] TRUE
FALSE | TRUE
## [1] TRUE
## [1] TRUE
19
Chapter 1 Programming Basics
## [1] FALSE
All of the logic tests mentioned so far apply just as well to vectors as they apply to
single objects:
If you want only a single response, such as for if/else flow control, you can use &&
or ——, which stop evaluating as soon as they have determined the final result. Work
through the following code and output carefully:
TRUE | W
## BUT
TRUE || W
## [1] TRUE
W || TRUE
20
Chapter 1 Programming Basics
FALSE & W
FALSE && W
## [1] FALSE
Note that the double operators are not, in fact, vectorized. They simply use the first
element of any vectors:
## [1] TRUE
## [1] TRUE
The any() and all() functions are helpful as well in these contexts for similar
reasons:
## [1] TRUE
## [1] FALSE
## [1] TRUE
21
Chapter 1 Programming Basics
3 + 3
## [1] 6
3 – 3
## [1] 0
3 * 3
## [1] 9
3 / 3
## [1] 1
(-27) ˆ (1/3)
## [1] NaN
4 %/% .7
## [1] 5
4 %% .3
## [1] 0.1
sqrt(3)
## [1] 1.7
abs(-3)
## [1] 3
exp(1)
## [1] 2.7
log(2.71)
## [1] 1
22
Chapter 1 Programming Basics
Trigonometric functions also have their part, and ?Trig can bring up a nice list of
these. We show cosine’s function call cos() for brevity. Note the slight inaccuracy again
on the cosine function’s output:
cos(3.1415) ## cosine
## [1] -1
?Trig
We close this section and this chapter with a brief selection of matrix operations.
Scalar operations use the basic arithmetic operators. To perform matrix multiplication,
we use %*%:
x2
## [,1] [,2]
## [1,] 1 4
## [2,] 2 5
## [3,] 3 6
x2 * 3
## [,1] [,2]
## [1,] 3 12
## [2,] 6 15
## [3,] 9 18
x2 + 3
## [,1] [,2]
## [1,] 4 7
## [2,] 5 8
## [3,] 6 9
## [,1]
## [1,] 5
## [2,] 7
## [3,] 9
23
Chapter 1 Programming Basics
Matrices have a few other fairly common operations that are helpful in linear
algebra. For some of the modeling applications we cover later on, we discuss an
appropriate amount of mathematics as needed in the following chapters. Still, this seems
a good place to show how the transpose, cross product, and transpose cross product
might be coded. We show both the raw code to make the cross product and transpose
cross product occur and easier function calls that may be used. This is a relatively
common occurrence in R, incidentally. Through packages, quite a few techniques are
implemented in fairly clear function calls. Here are the examples:
## transpose
t(x2)
## cross product
t(x2) %*% x2
## [,1] [,2]
## [1,] 14 32
## [2,] 32 77
## [,1] [,2]
## [1,] 14 32
## [2,] 32 77
24
Chapter 1 Programming Basics
As you have just seen, it is common in R for someone else to have done the heavy
lifting by making a function that outputs the desired outcome. Of course, these friendly
programmers’ work is subjected to only the underlying constraints of R itself as well as
the ability to acquire a free GitHub account. User, beware (at least in some cases)! Thus,
it can be helpful to understand the base commands and operators that make R work.
Next, let’s focus on understanding implementation nuances as well as quickly getting
data in and out of R.
1.6 Summary
We will conclude each chapter with a summary Table 1-2 of any R concepts of major
import. These will generally be functions, although some objects will be worth
discussing too in the case of this chapter.
26
CHAPTER 2
Programming Utilities
One of the powerful features of R is the highly skilled, kindly community of enthusiasts,
developers, and package authors. In particular, to extend the functionality of base R, one
can find and add packages which in turn allow one to use new functions.
As a reminder, in R, functions tend to be actions our code takes to create an output or
result based on one or more inputs (also called formals). While we save a discussion for
how to code your own functions for another chapter, using functions created and shared
in the R community provides highly helpful additions to what R can do.
In particular, we will focus in this chapter on functions for learning more about
functions, operating system environment and file management, and data input and
output to and from R:
27
© Matt Wiley and Joshua F. Wiley 2020
M. Wiley and J. F. Wiley, Advanced R 4 Data Programming and the Cloud,
https://doi.org/10.1007/978-1-4842-5973-3_2
Chapter 2 Programming Utilities
In the following code, we commented out the installation of our already familiar
data.table [9] as well as our new-in-this-chapter haven [33], readxl [27], and writexl
[13]. While we run the library() function now, we will discuss each package more in
depth when we use it for the first time later inside this chapter. To run commented code,
simply do not include the hashtag or pound sign when using that line of code. Please
note that R is case sensitive when typing the package and function names.
With that, you now have five packages that add extra features to our journey in this
chapter. Notice that it was required to know the names of the packages. As a general rule,
such names of time- and work-saving packages are learned from social media—#rstats
is a common tag on a certain bird-related app—by following certain popular package
authors, by reading blogs of various sorts online, or by reading books such as this
offering. Many R authors (present company included) and package creators tend to share
vignettes and packages via social media.
?'+'
help("+")
28
Chapter 2 Programming Utilities
Sys.Date()
## [1] "2020-04-29"
Sys.time()
Sys.timezone()
## [1] "America/Chicago"
30
Chapter 2 Programming Utilities
The help documentation for these commands makes useful suggestions to increase
the accuracy of the output, up to potentially millisecond or microsecond precision.
For troubleshooting purposes, the Sys.getenv() function can be very helpful to
understand a great many defaults of your R environment and default. While it is safe
enough to run the command, due to the machine-specific (and personal) information
output, we elect to not show the output here. All the same, it can be interesting to “see
under the hood” of your R environment.
As we turn our attention to a variety of file management functions, a word of caution:
R has the same privileges you do, and some of these file functions can delete files, can
write enough files to fill up a drive, and in general should be handled with a bit of care.
That being said, sometimes you need to work with a large collection of files “at scale,”
and they are all useful, if powerful. These functions share the format file. and have as
their first argument a character vector that should be either a filename for the current
working directory or a path and filename. We start with a text file ch02_text.txt inside
two folders data/ch02 under our working directory.
Note For the following examples, we recommend you have downloaded the full
file collection from this book’s GitHub site (see details in Chapter 1). If not, then
inside your working directory, you will need to create a folder named data; inside
that folder, create a subfolder named ch02; and inside that, create a blank text
file named ch02_text.txt. In either case, it is not necessarily likely that your
output will quite match ours here, since the time of file creation and copy over will
change. However, the structure should remain true.
The function file.exists() takes only a character string input, which is a filename
or a path and filename. If it is simply a filename, it checks only the working directory.
This working directory may be verified by the getwd() function (another function that,
while safe to run, we will avoid). If a check is desired for a file in another directory, this
may be done by giving a full file path inside the string. This function returns a logical
value of either TRUE or FALSE. Depending on user permissions for a particular file, you
may not get the expected result for a particular file. In other words, if you do not have
permission to access a file (such as on a shared network drive), an existence check may
return false, even if the file does exist:
31
Chapter 2 Programming Utilities
## [1] TRUE
## [1] FALSE
While the preceding function checks for existence, another function tests for
whether we have access to a file. The function file.access() takes similar input, except
it also takes a second argument. To test for existence, the second argument is 0. To
test for executable permissions, use 1; and to test for writing permission, use 2. If you
want to test your ability to read a file, use 4. This function returns an integer vector of
0 to indicate that permissions are given and -1 to indicate permissions are not given.
Notice that the default for the function is to test for simple existence. Examples of file.
access() are shown here:
file.access("data/ch02/ch02_text.txt", mode = 0)
## data/ch02/ch02_text.txt
## 0
file.access("data/ch02/ch02_text.txt", mode = 1)
## data/ch02/ch02_text.txt
## -1
file.access("data/ch02/ch02_text.txt", mode = 2)
## data/ch02/ch02_text.txt
## 0
file.access("data/ch02/ch02_text.txt", mode = 4)
## data/ch02/ch02_text.txt
## 0
32
Chapter 2 Programming Utilities
To learn more detailed information about when a file was modified, changed, or
accessed, use the file.info() function. This function takes in character strings as well.
The output gives information about the file size; whether it is a directory; a file
permissions integer in read, write, and execute order; the last modified time; the last
change time; the last accessed time; and, finally, whether the file is executable:
file.info("data/ch02/ch02_text.txt", "NOSUCHFILE.FAKE")
## size isdir mode mtime
## data/ch02/ch02_text.txt 31 FALSE 666 2020-04-25 17:03:35
## NOSUCHFILE.FAKE NA NA <NA> <NA>
## ctime atime exe
## data/ch02/ch02_text.txt 2020-02-15 15:27:15 2020-04-25 17:03:55 no
## NOSUCHFILE.FAKE <NA> <NA> <NA>
Using the idea of storing data in a variable from Chapter 1, consider assigning the
results of a file to a variable name such as ch02FileData. This is in fact a data frame
and may be treated as such. Columns can be accessed, values determined, and logical
operations performed to understand which files might be above a certain size. In the
following code, we read in the system information for two potential files, determine that
this is indeed a data frame, and inspect one of the columns more closely, before finally
performing some logical tests on that column:
## [1] TRUE
ch02FileData$size
## [1] 31 NA
is.numeric(ch02FileData$size)
## [1] TRUE
ch02FileData$size > 5
## [1] TRUE NA
33
Another random document with
no related content on Scribd:
a clergyman in the North, who suffered from ‘clergyman’s sore
throat’; he was a popular evangelical preacher, and there was no
end to the sympathy his case evoked; he couldn’t preach, so his
devoted congregation sent him, now to the South of France, now to
Algiers, now to Madeira. After each delightful sojourn he returned,
looking plump and well, but unable to raise his voice above a hardly
audible whisper. This went on for three years or so. Then his Bishop
interfered; he must provide a curate in permanent charge, with
nearly the full emoluments of the living. The following Sunday he
preached, nor did he again lose his voice. And this was an earnest
and honest man, who would rather any day be at his work than
wandering idly about the world. Plainly, too, in the etymological
sense of the word, his complaint was not hysteria. But this is not an
exceptional case: keep any man in his dressing-gown for a week or
two—a bad cold, say—and he will lay himself out to be pitied and
petted, will have half the ailments under the sun, and be at death’s
door with each. And this is your active man; a man of sedentary
habits, notwithstanding his stronger frame, is nearly as open as a
woman to the advances of this stealthy foe. Why, for that matter, I’ve
seen it in a dog! Did you never see a dog limp pathetically on his
three legs that he might be made much of for his lameness, until his
master’s whistle calls him off at a canter on all fours?”
“I get no nearer; what have these illustrations to do with my wife?”
“Wait a bit, and I’ll try to show you. The throat would seem to be a
common seat of the affection. I knew a lady—nice woman she was,
too—who went about for years speaking in a painful whisper, whilst
everybody said, ‘Poor Mrs. Marjoribanks!’ But one evening she
managed to set her bed-curtains alight, when she rushed to the door,
screaming, ‘Ann! Ann! the house is on fire! Come at once!’ The dear
woman believed ever after, that ‘something burst’ in her throat, and
described the sensation minutely; her friends believed, and her
doctor did not contradict. By the way, no remedy has proved more
often effectual than a house on fire, only you will see the difficulties. I
knew of a case, however, where the ‘house-afire’ prescription was
applied with great effect. ’Twas in a London hospital for ladies; a
most baffling case; patient had been for months unable to move a
limb—was lifted in and out of bed like a log, fed as you would pour
into a bottle. A clever young house-surgeon laid a plot with the
nurses. In the middle of the night her room was filled with fumes,
lurid light, &c. She tried to cry out, but the smoke was suffocating;
she jumped out of bed and made for the door—more choking smoke
—threw up the sash—fireman, rope, ladder—she scrambled down,
and was safe. The whole was a hoax, but it cured her, and the
nature of the cure was mercifully kept secret. Another example: A
friend of mine determined to put a young woman under ‘massage’ in
her own home; he got a trained operator, forbade any of her family to
see her, and waited for results. The girl did not mend; ‘very odd!
some reason for this,’ he muttered; and it came out that every night
the mother had crept in to wish her child good-night; the tender visits
were put a stop to, and the girl recovered.”
“Your examples are interesting enough, but I fail to see how they
bear; in each case, you have a person of weak or disordered intellect
simulating a disease with no rational object in view. Now the beggars
who know how to manufacture sores on their persons have the
advantage—they do it for gain.”
“I have told my tale badly; these were not persons of weak or
disordered intellect; some of them very much otherwise; neither did
they consciously simulate disease; not one believed it possible to
make the effort he or she was surprised into. The whole question
belongs to the mysterious borderland of physical and psychological
science—not pathological, observe; the subject of disease and its
treatment is hardly for the lay mind.”
“I am trying to understand.”
“It is worth your while; if every man took the pains to understand
the little that is yet to be known on this interesting subject he might
secure his own household, at any rate, from much misery and waste
of vital powers; and not only his household, but perhaps himself—for,
as I have tried to show, this that is called ‘hysteria’ is not necessarily
an affair of sex.”
“Go on; I am not yet within appreciable distance of anything
bearing on my wife’s case.”
“Ah, the thing is a million-headed monster! hardly to be
recognised by the same features in any two cases. To get at the
rationale of it, we must take up human nature by the roots. We talk
glibly in these days of what we get from our forefathers, what comes
to us through our environment, and consider that in these two we
have the sum of human nature. Not a bit of it; we have only
accounted for some peculiarities in the individual; independently of
these, we come equipped with stock for the business of life of which
too little account is taken. The subject is wide, so I shall confine
myself to an item or two.
“We all come into the world—since we are beings of imperfect
nature—subject to the uneasy stirring of some few primary desires.
Thus, the gutter child and the infant prince are alike open to the
workings of the desire for esteem, the desire for society, for power,
&c. One child has this, and another that, desire more active and
uneasy. Women, through the very modesty and dependence of their
nature, are greatly moved by the desire for esteem. They must be
thought of, made much of, at any price. A man desires esteem, and
he has meetings in the marketplace, the chief-room at the feast; the
pétroleuse, the city outcast, must have notoriety—the esteem of the
bad—at any price, and we have a city in flames, and Whitechapel
murders. Each falls back on his experience and considers what will
bring him that esteem, a gnawing craving after which is one of his
earliest immaterial cognitions. But the good woman has
comparatively few outlets. The esteem that comes to her is all within
the sphere of her affections. Esteem she must have; it is a necessity
of her nature.
“‘Praise, blame, love, kisses, tears, and smiles,’
are truly to her, ‘human nature’s daily food.’”
“Now, experience comes to her aid. When she is ill, she is the
centre of attraction, the object of attention, to all who are dear to her;
she will be ill.”
“You contradict yourself, man! don’t you see? You are painting,
not a good woman, but one who will premeditate, and act a lie!”
“Not so fast! I am painting a good woman. Here comes in a
condition which hardly any one takes into account. Mrs. Jumeau will
lie with stiffened limbs and blue pale face for hours at a time. Is she
simulating illness? you might as well say that a man could simulate a
gunshot wound. But the thing people forget is, the intimate relation
and co-operation of body and mind; that the body lends itself
involuntarily to carry out the conceptions of the thinking brain. Mrs.
Jumeau does not think herself into pallor, but every infinitesimal
nerve fibre, which entwines each equally infinitesimal capillary which
brings colour to the cheek, is intimately connected with the thinking
brain, in obedience to whose mandates it relaxes or contracts. Its
relaxation brings colour and vigour with the free flow of the blood, its
contraction, pallor, and stagnation; and the feeling as well as the look
of being sealed in a death-like trance. The whole mystery depends
on this co-operation of thought and substance of which few women
are aware. The diagnosis is simply this, the sufferer has the craving
for outward tokens of the esteem which is essential to her nature;
she recalls how such tokens accompany her seasons of illness, the
sympathetic body perceives the situation, and she is ill; by-and-by,
the tokens of esteem cease to come with the attacks of illness, but
the habit has been set up, and she goes on having ‘attacks ’ which
bring real suffering to herself, and of the slightest agency in which
she is utterly unconscious.”
Conviction slowly forced itself on Mr. Jumeau; now that his wife
was shown entirely blameless, he could concede the rest. More, he
began to suspect something rotten in the State of Denmark, or
women like his wife would never have been compelled to make so
abnormal a vent for a craving proper to human nature.
“I begin to see; what must I do?”
“In Mrs. Jumeau’s case, I may venture to recommend a course
which would not answer with one in a thousand. Tell her all I have
told you. Make her mistress of the situation.—I need not say, save
her as much as you can from the anguish of self-contempt. Trust her,
she will come to the rescue, and devise means to save herself; and,
all the time, she will want help from you, wise as well as tender. For
the rest, those who have in less measure—
“‘The reason firm, the temp’rate will’—
‘massage,’ and other devices for annulling the extraordinary physical
sensibility to mental conditions, and, at the same time, excluding the
patient from the possibility of the affectionate notice she craves, may
do a great deal. But this mischief which, in one shape or other,
blights the lives of, say, forty per cent. of our best and most highly
organised women, is one more instance of how lives are ruined by
an education which is not only imperfect, but proceeds on wrong
lines.”
“How could education help in this?”
“Why, let them know the facts, possess them of even so slight an
outline as we have had to-night, and the best women will take
measures for self-preservation. Put them on their guard, that is all. It
is not enough to give them accomplishments and all sorts of higher
learning; these gratify the desire of esteem only in a very temporary
way. But something more than a danger-signal is wanted. The
woman, as well as the man, must have her share of the world’s
work, whose reward is the world’s esteem. She must, even the
cherished wife and mother of a family, be in touch with the world’s
needs, and must minister of the gifts she has; and that, because it is
no dream that we are all brethren, and must therefore suffer from
any seclusion from the common life.”
Mrs. Jumeau’s life was not “spoilt.” It turned out as the doctor
predicted; for days after his revelations she was ashamed to look her
husband in the face; but then, she called up her forces, fought her
own fight and came off victorious.
CHAPTER IX
PARENTS IN COUNCIL
Part I
“Now, let us address ourselves to the serious business of the
evening. Here we are:
‘Six precious (pairs), and all agog,
To dash through thick and thin!’
FOOTNOTES:
[23] Ancient history now; a forecast fulfilled in the formation
of the Parents’ National Educational Union.