<- vector("numeric", length = 2) #empty vector: Zeros
num_vec num_vec
[1] 0 0
class(num_vec)
[1] "numeric"
length(num_vec)
[1] 2
After this lesson, you should be able to:
[
by index, name, logical vector, and indirectly with objects$
and [[
str()
function to examine the structure of an unfamiliar object and extract components from the objectVector: A vector is a collection of elements of the same type (e.g., numeric, integer, character, logical).
. . .
<- vector("numeric", length = 2) #empty vector: Zeros
num_vec num_vec
[1] 0 0
class(num_vec)
[1] "numeric"
length(num_vec)
[1] 2
. . .
<- vector("logical", length = 3) #empty vector: FALSE
log_vec log_vec
[1] FALSE FALSE FALSE
class(log_vec)
[1] "logical"
length(log_vec)
[1] 3
. . .
<- vector("character", length = 4) #empty vector: empty strings
chr_vec chr_vec
[1] "" "" "" ""
class(chr_vec)
[1] "character"
length(chr_vec)
[1] 4
. . .
<- c('name1' = 1, 'name2' = 2) # Named numeric vector
named_vec named_vec
name1 name2
1 2
class(named_vec)
[1] "numeric"
length(named_vec)
[1] 2
. . .
List: A list is a collection of elements (e.g., vectors, matrices, data frames, other lists).
. . .
<- list(a = 1:3, b = c("a", "b", "c"), c = matrix(1:6, nrow = 2))
ex_list ex_list
$a
[1] 1 2 3
$b
[1] "a" "b" "c"
$c
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
class(ex_list)
[1] "list"
length(ex_list) # number of elements in a list
[1] 3
Array: An array is a vector with a dimension attribute.
<- array(NA, dim = c(2,3,4))
ary ary
, , 1
[,1] [,2] [,3]
[1,] NA NA NA
[2,] NA NA NA
, , 2
[,1] [,2] [,3]
[1,] NA NA NA
[2,] NA NA NA
, , 3
[,1] [,2] [,3]
[1,] NA NA NA
[2,] NA NA NA
, , 4
[,1] [,2] [,3]
[1,] NA NA NA
[2,] NA NA NA
class(ary)
[1] "array"
length(ary) # The number of elements in a array is the product of its dimensions
[1] 24
dim(ary) # Get the dimensions of the array
[1] 2 3 4
. . .
Matrix: A matrix is an array with only 2 dimensions (rows, columns).
<- matrix(NA, nrow = 2, ncol = 3)
m m
[,1] [,2] [,3]
[1,] NA NA NA
[2,] NA NA NA
class(m)
[1] "matrix" "array"
length(m) # The number of elements in a matrix is the product of its dimensions
[1] 6
dim(m) # Get the dimensions of the matrix
[1] 2 3
. . .
Data Frame/tibble: A data frame is a named list with elements of equal length.
<- tibble(x = 1:10, y = 1:10 + rnorm(10))
mod_df
<- tibble(a = 1:3, b = c("constant", "x", "x squared"), d = list(lm(y ~ 1, data = mod_df), lm(y ~ x, data = mod_df), lm(y ~ x + I(x^2), data = mod_df)))
df df
# A tibble: 3 × 3
a b d
<int> <chr> <list>
1 1 constant <lm>
2 2 x <lm>
3 3 x squared <lm>
length(df) # number of "elements" in a data frame is the number of "columns"
[1] 3
The content here comes from Chapter 27 of R4DS, with some small additions.
[
We can subset common R structures and maintain the class structure with [ ]
.
There are four main types of things that you can subset with, i.e., that can be the i
in x[i]
:
# Vectors
<- c("one", "two", "three", "four", "five")
x c(3, 2, 5)] x[
[1] "three" "two" "five"
2:4] x[
[1] "two" "three" "four"
class(x[2:4]) # result is a character vector
[1] "character"
. . .
# Lists
<- list(a = 1:3, b = c("a", "b", "c"), c = matrix(1:6, nrow = 2))
y c(1, 2)] y[
$a
[1] 1 2 3
$b
[1] "a" "b" "c"
class(y[c(1)]) # result is a list
[1] "list"
. . .
By repeating a position, you can actually make a longer output than input, making the term “subsetting” a bit of a misnomer.
# Vector
c(1, 1, 2)] x[
[1] "one" "one" "two"
# List
c(1, 1, 2)] y[
$a
[1] 1 2 3
$a
[1] 1 2 3
$b
[1] "a" "b" "c"
. . .
# Vector
c(-1, -3, -5)] x[
[1] "two" "four"
# List
c(-1)] y[
$b
[1] "a" "b" "c"
$c
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
. . .
TRUE
. This is generally used with comparison functions and operators.# Vector
<- c(10, 3, NA, 5, 8, 1, NA)
x
# All non-missing values of x
!is.na(x)] x[
[1] 10 3 5 8 1
# All values greater than 5, with NAs
> 5] x[x
[1] 10 NA 8 NA
# All non-missing values greater than 5
> 5 & !is.na(x)] x[x
[1] 10 8
. . .
Unlike filter()
, NA
indices will be included in the output as NA
s unless you explicitly remove them (filter()
removes instances of missing values by default.
# Compare with filter
filter(tibble(x = x), x > 5)
# A tibble: 2 × 1
x
<dbl>
1 10
2 8
. . .
# List
c(TRUE, FALSE, TRUE)] y[
$a
[1] 1 2 3
$c
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
%>% map_lgl(~ is.numeric(.x))] # example of a map function! y[y
$a
[1] 1 2 3
$c
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
%>% map_lgl(~ is.character(.x))] y[y
$b
[1] "a" "b" "c"
. . .
# Named Vector
<- c(abc = 1, def = 2, xyz = 5)
x c("xyz", "def")] x[
xyz def
5 2
c("xyz","xyz","xyz", "def")] x[
xyz xyz xyz def
5 5 5 2
#Named List
c('a','a','c')] y[
$a
[1] 1 2 3
$a
[1] 1 2 3
$c
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
As with subsetting with positive integers, you can use a character vector to duplicate individual entries.
. . .
Be very wary of vector recycling when doing this! The number of things that you’re inserting should either be 1 or the size of the x[i]
subset.
<- c(first = "one", second = "two", third = "three", fourth = "four")
x x
first second third fourth
"one" "two" "three" "four"
. . .
c(1, 3)] <- "new" # Replacement length is 1
x[ x
first second third fourth
"new" "two" "new" "four"
. . .
<- c(first = "one", second = "two", third = "three", fourth = "four")
x c(1, 3)] <- c("new1", "new2") # Replacement length is 2, and length of subset is 2
x[ x
first second third fourth
"new1" "two" "new2" "four"
. . .
<- c(first = "one", second = "two", third = "three", fourth = "four")
x c(1, 3, 4)] <- c("new1", "new2") # BAD! Replacement length is 2, and length of subset is 3
x[ x
first second third fourth
"new1" "two" "new2" "new1"
. . .
<- c(first = "one", second = "two", third = "three", fourth = "four")
x c(1, 3)] <- c("new1", "new2", "new3") # BAD! Replacement length is 3, and length of subset is 2
x[ x
first second third fourth
"new1" "two" "new2" "four"
[
All of the above subsetting options can be used for subsetting matrices and data frames (named list of elements of equal length).
<- matrix(1:12, nrow = 3, ncol = 4)
m m
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
1:5] # Matrix = vector (down the columns) with dimensions m[
[1] 1 2 3 4 5
You can use a comma to subset by rows and columns separately.
1,] # Get 1st row m[
[1] 1 4 7 10
1] # Get 1st column m[,
[1] 1 2 3
. . .
1,3] # Get 1st row and 3rd column m[
[1] 7
c(1,3),] # Get 1st and 3rd rows m[
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 3 6 9 12
c(1,3)] # Get 1st and 3rd columns m[,
[,1] [,2]
[1,] 1 7
[2,] 2 8
[3,] 3 9
c(1,3),c(1,3)] # Get 1st and 3rd rows and 1st and 3rd columns m[
[,1] [,2]
[1,] 1 7
[2,] 3 9
-1,] # Get all rows except 1st m[
[,1] [,2] [,3] [,4]
[1,] 2 5 8 11
[2,] 3 6 9 12
c(TRUE, FALSE, FALSE),] # Get the 1st row via a logical m[
[1] 1 4 7 10
# Add row and column names to the matrix
colnames(m) <- str_c("col", 1:4)
rownames(m) <- str_c("row", 1:3)
"row1",] m[
col1 col2 col3 col4
1 4 7 10
$
and [[
We can use $
and [[
to extract a single column of a data frame or an element within a list. This breaks out of the original class structure.
mtcars
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4
Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4
Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3
Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4
Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4
Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4
Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1
Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2
AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2
Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4
Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2
Fiat X1-9 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1
Porsche 914-2 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2
Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
Ford Pantera L 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5 4
Ferrari Dino 19.7 6 145.0 175 3.62 2.770 15.50 0 1 5 6
Maserati Bora 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5 8
Volvo 142E 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4 2
$mpg mtcars
[1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4
[16] 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7
[31] 15.0 21.4
"mpg"]] mtcars[[
[1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4
[16] 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7
[31] 15.0 21.4
%>% pull(mpg) mtcars
[1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2 10.4
[16] 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4 15.8 19.7
[31] 15.0 21.4
seq()
function.)str()
The str()
function shows you the structure of an object and is useful for exploring model objects and objects created from packages that are new to you.
In the output of str()
dollar signs indicate named components of a list that can be extracted via $
or [[
.
. . .
We see that both mod
and mod_summ
are lists, so we can also interactively view these objects with View(mod)
and View(mod_summ)
in the Console.
<- lm(mpg ~ hp + wt, data = mtcars)
mod <- summary(mod)
mod_summ
str(mod)
List of 12
$ coefficients : Named num [1:3] 37.2273 -0.0318 -3.8778
..- attr(*, "names")= chr [1:3] "(Intercept)" "hp" "wt"
$ residuals : Named num [1:32] -2.572 -1.583 -2.476 0.135 0.373 ...
..- attr(*, "names")= chr [1:32] "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet 4 Drive" ...
$ effects : Named num [1:32] -113.65 -26.046 -15.894 0.447 0.662 ...
..- attr(*, "names")= chr [1:32] "(Intercept)" "hp" "wt" "" ...
$ rank : int 3
$ fitted.values: Named num [1:32] 23.6 22.6 25.3 21.3 18.3 ...
..- attr(*, "names")= chr [1:32] "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet 4 Drive" ...
$ assign : int [1:3] 0 1 2
$ qr :List of 5
..$ qr : num [1:32, 1:3] -5.657 0.177 0.177 0.177 0.177 ...
.. ..- attr(*, "dimnames")=List of 2
.. .. ..$ : chr [1:32] "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet 4 Drive" ...
.. .. ..$ : chr [1:3] "(Intercept)" "hp" "wt"
.. ..- attr(*, "assign")= int [1:3] 0 1 2
..$ qraux: num [1:3] 1.18 1.08 1.09
..$ pivot: int [1:3] 1 2 3
..$ tol : num 1e-07
..$ rank : int 3
..- attr(*, "class")= chr "qr"
$ df.residual : int 29
$ xlevels : Named list()
$ call : language lm(formula = mpg ~ hp + wt, data = mtcars)
$ terms :Classes 'terms', 'formula' language mpg ~ hp + wt
.. ..- attr(*, "variables")= language list(mpg, hp, wt)
.. ..- attr(*, "factors")= int [1:3, 1:2] 0 1 0 0 0 1
.. .. ..- attr(*, "dimnames")=List of 2
.. .. .. ..$ : chr [1:3] "mpg" "hp" "wt"
.. .. .. ..$ : chr [1:2] "hp" "wt"
.. ..- attr(*, "term.labels")= chr [1:2] "hp" "wt"
.. ..- attr(*, "order")= int [1:2] 1 1
.. ..- attr(*, "intercept")= int 1
.. ..- attr(*, "response")= int 1
.. ..- attr(*, ".Environment")=<environment: R_GlobalEnv>
.. ..- attr(*, "predvars")= language list(mpg, hp, wt)
.. ..- attr(*, "dataClasses")= Named chr [1:3] "numeric" "numeric" "numeric"
.. .. ..- attr(*, "names")= chr [1:3] "mpg" "hp" "wt"
$ model :'data.frame': 32 obs. of 3 variables:
..$ mpg: num [1:32] 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
..$ hp : num [1:32] 110 110 93 110 175 105 245 62 95 123 ...
..$ wt : num [1:32] 2.62 2.88 2.32 3.21 3.44 ...
..- attr(*, "terms")=Classes 'terms', 'formula' language mpg ~ hp + wt
.. .. ..- attr(*, "variables")= language list(mpg, hp, wt)
.. .. ..- attr(*, "factors")= int [1:3, 1:2] 0 1 0 0 0 1
.. .. .. ..- attr(*, "dimnames")=List of 2
.. .. .. .. ..$ : chr [1:3] "mpg" "hp" "wt"
.. .. .. .. ..$ : chr [1:2] "hp" "wt"
.. .. ..- attr(*, "term.labels")= chr [1:2] "hp" "wt"
.. .. ..- attr(*, "order")= int [1:2] 1 1
.. .. ..- attr(*, "intercept")= int 1
.. .. ..- attr(*, "response")= int 1
.. .. ..- attr(*, ".Environment")=<environment: R_GlobalEnv>
.. .. ..- attr(*, "predvars")= language list(mpg, hp, wt)
.. .. ..- attr(*, "dataClasses")= Named chr [1:3] "numeric" "numeric" "numeric"
.. .. .. ..- attr(*, "names")= chr [1:3] "mpg" "hp" "wt"
- attr(*, "class")= chr "lm"
str(mod_summ)
List of 11
$ call : language lm(formula = mpg ~ hp + wt, data = mtcars)
$ terms :Classes 'terms', 'formula' language mpg ~ hp + wt
.. ..- attr(*, "variables")= language list(mpg, hp, wt)
.. ..- attr(*, "factors")= int [1:3, 1:2] 0 1 0 0 0 1
.. .. ..- attr(*, "dimnames")=List of 2
.. .. .. ..$ : chr [1:3] "mpg" "hp" "wt"
.. .. .. ..$ : chr [1:2] "hp" "wt"
.. ..- attr(*, "term.labels")= chr [1:2] "hp" "wt"
.. ..- attr(*, "order")= int [1:2] 1 1
.. ..- attr(*, "intercept")= int 1
.. ..- attr(*, "response")= int 1
.. ..- attr(*, ".Environment")=<environment: R_GlobalEnv>
.. ..- attr(*, "predvars")= language list(mpg, hp, wt)
.. ..- attr(*, "dataClasses")= Named chr [1:3] "numeric" "numeric" "numeric"
.. .. ..- attr(*, "names")= chr [1:3] "mpg" "hp" "wt"
$ residuals : Named num [1:32] -2.572 -1.583 -2.476 0.135 0.373 ...
..- attr(*, "names")= chr [1:32] "Mazda RX4" "Mazda RX4 Wag" "Datsun 710" "Hornet 4 Drive" ...
$ coefficients : num [1:3, 1:4] 37.22727 -0.03177 -3.87783 1.59879 0.00903 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : chr [1:3] "(Intercept)" "hp" "wt"
.. ..$ : chr [1:4] "Estimate" "Std. Error" "t value" "Pr(>|t|)"
$ aliased : Named logi [1:3] FALSE FALSE FALSE
..- attr(*, "names")= chr [1:3] "(Intercept)" "hp" "wt"
$ sigma : num 2.59
$ df : int [1:3] 3 29 3
$ r.squared : num 0.827
$ adj.r.squared: num 0.815
$ fstatistic : Named num [1:3] 69.2 2 29
..- attr(*, "names")= chr [1:3] "value" "numdf" "dendf"
$ cov.unscaled : num [1:3, 1:3] 3.80e-01 2.21e-05 -1.09e-01 2.21e-05 1.21e-05 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : chr [1:3] "(Intercept)" "hp" "wt"
.. ..$ : chr [1:3] "(Intercept)" "hp" "wt"
- attr(*, "class")= chr "summary.lm"
tibble
) with the coefficient estimate and CI for the predictor of interest. It should take the following inputs:data
: A datasetyvar
: Outcome variable to be used in a linear model (a length-1 character vector)preds
: Predictor variables to be used in a linear model (a character vector)pred_of_interest
: The variable whose coefficient estimate and confidence interval are of interest (a length-1 character vector and should be one of preds
)Development tip: As you develop, it will help to create objects for the arguments so that you can see what output looks like interactively:
Test your function on the mtcars
dataset.
<- mtcars
data <- "mpg"
yvar <- c("hp", "wt")
preds <- "hp" pred_of_interest
When you’re done developing your function, remove these objects to declutter your environment by entering rm(data, yvar, preds, pred_of_interest)
in the Console.
<- function(___) {
fit_mod_and_extract # Use str_c to create a string (formula_str) that looks like "yvar ~ pred1 + pred2"
# Look at the documentation for a helpful argument
<-
mod_formula_str <- as.formula(mod_formula_str)
mod_form
# Fit a linear model using the constructed formula and given data
<- lm(mod_form, data = data)
mod
# Obtain 95% confidence interval
<- confint(mod, level = 0.95)
ci
# Return the coefficient estimate and CI for the predictor of interest
tibble(
which_pred = pred_of_interest,
estimate = ___,
ci_lower = ___,
ci_upper = ___
) }
When writing functions and working with functions that you wrote, you may encounter errors that are hard to figure out.
Here are some strategies to help you debug the issues you encounter:
print()
and cat()
to print out intermediate results and messages within a function.
print(x)
, cat("The value of x is", x, "\n")
<- function(x){
My_own_sum print(x)
return(sum(x))
}My_own_sum(c(1,2,3))
<- function(x){
My_own_sum cat("The value of x is", x, "\n")
cat("The class of x is", class(x), "\n")
return(sum(x))
}
My_own_sum(c(1,2,3))
. . .
browser()
to pause the function at a certain point and interactively explore the environment. Press “Next” or type n
to run the next line of code. Type the name of an object in the Console to see its value at this point in the function. You can type Q
to quit the browser.
<- function(data, yvar, preds, pred_of_interest) {
fit_mod_and_extract # Use str_c to create a string (formula_str) that looks like "yvar ~ pred1 + pred2"
# Look at the documentation for a helpful argument
<- str_c(yvar, "~", str_c(preds, collapse = "+"))
mod_formula_str <- as.formula(mod_formula_str)
mod_form
# Add browser() to where in the function you'd like to pause and interact in the function environment using the Console
browser()
# Fit a linear model using the constructed formula and given data
<- lm(mod_form, data = data)
mod
# Obtain 95% confidence interval
<- confint(mod, level = 0.95)
ci
# Return the coefficient estimate and CI for the predictor of interest
tibble(
which_pred = pred_of_interest,
estimate = mod$coefficients[pred_of_interest],
ci_lower = ci[pred_of_interest, "2.5 %"],
ci_upper = ci[pred_of_interest, "97.5 %"]
)
}
fit_mod_and_extract(data = mtcars, yvar = "mpg", preds = c("hp", "wt"), pred_of_interest = "hp")
. . .
try()
to catch errors and print out a message when an error occurs.
<- function(x){
My_own_sum return(sum(x))
}
<- My_own_sum(c("a","b","c")) results
Error in sum(x): invalid 'type' (character) of argument
class(results)
Error: object 'results' not found
<- try(My_own_sum(c("a","b","c")), silent = TRUE)
results class(results)
[1] "try-error"
. . .
if else
statements within a function to ensure that you are passing the right type of input to a function. You can create you own custom error message with stop()
.
<- function(x){
My_own_sum if(!is.numeric(x)){
stop("Input must be numeric")
}return(sum(x))
}
<- My_own_sum(c("a","b","c")) results
Error in My_own_sum(c("a", "b", "c")): Input must be numeric
class(results)
[1] "try-error"
<- try(My_own_sum(c("a","b","c")), silent = TRUE)
results class(results)
[1] "try-error"
<- function(x) {
get_even_pos if (length(x) <= 1) {
print("No even positions")
else {
} <- seq(2, length(x), by = 2)
idx
x[idx]
}
}get_even_pos(1:10)
[1] 2 4 6 8 10
get_even_pos(1:9)
[1] 2 4 6 8
get_even_pos(1)
[1] "No even positions"
<- function(x) {
get_all_but_last head(x, -1)
# x[1:(length(x)-1)]
}get_all_but_last(1:10)
[1] 1 2 3 4 5 6 7 8 9
<- function(x) {
get_evens %% 2 == 0 & !is.na(x)]
x[x
}
get_evens(c(1, 2, 7, NA))
[1] 2
get_evens(c(1, 2, 7, 8, NA))
[1] 2 8
<- function(data, yvar, preds, pred_of_interest) {
fit_mod_and_extract # Use str_c to create a string (formula_str) that looks like "yvar ~ pred1 + pred2"
# Look at the documentation for a helpful argument
<- str_c(yvar, "~", str_c(preds, collapse = "+"))
mod_formula_str <- as.formula(mod_formula_str)
mod_form
# Fit a linear model using the constructed formula and given data
<- lm(mod_form, data = data)
mod
# Obtain 95% confidence interval
<- confint(mod, level = 0.95)
ci
# Return the coefficient estimate and CI for the predictor of interest
tibble(
which_pred = pred_of_interest,
estimate = mod$coefficients[pred_of_interest],
ci_lower = ci[pred_of_interest, "2.5 %"],
ci_upper = ci[pred_of_interest, "97.5 %"]
)
}
fit_mod_and_extract(data = mtcars, yvar = "mpg", preds = c("hp", "wt"), pred_of_interest = "hp")
# A tibble: 1 × 4
which_pred estimate ci_lower ci_upper
<chr> <dbl> <dbl> <dbl>
1 hp -0.0318 -0.0502 -0.0133