When do you use quotation marks, backticks, or nothing in R?
There are some inconsistencies across different functions, sometimes you just need to try them out. Always check that your work did what you expect!
In general these are the conventions for working with values (recall that values or samples within rows):
Type | Example | Features | Use |
---|---|---|---|
character string |
Liver
|
word | quotation marks - single or double |
character string |
New York
|
phrase | quotation marks - single or double |
atypical |
col 1
|
has spaces and numbers |
backticks
|
atypical |
col.1
|
has punctuation |
backticks
|
atypical |
1
|
just a number |
backticks
|
atypical |
1st col
|
starts with number |
backticks
|
Column names are slightly different. We will go over some of these situations in more detail, but here is a summary:
Function | Use |
---|---|
tibble() | Quotation marks okay, use backticks if atypical |
rename() | Quotation marks okay, use backticks if atypical |
filter() | Quotation marks not tolerated, use backticks if atypical |
summarize() | Quotation marks not tolerated, use backticks if atypical |
mutate() | Quotation marks okay, use backticks if atypical |
readr() | Quotation marks required |
tidyselect functions (ex.starts_with()) | Quotation marks required |
recode() | Quotation marks okay, use backticks if atypical |
separate() and unite() | See examples below |
case_when() | Quotation marks required |
stringr functions (ex. str_detect()) | Quotation marks required |
joins | Quotation marks okay, use backticks if atypical |
pivot_longer() / pivot_wider() | Quotation marks okay, use backticks if atypical |
modeling functions | Quotation marks not tolerated, use backticks if atypical |
tibble()
for naming variableswe suggest that you avoid nonstandard variable
names - standard names do not need any quotation marks or backticks
around the name within tibble
backticks are typically for nonstandard variable names (aka column names):
name with space
name!
12
1name
single or double quotation marks are typically used for character strings for the values within the data
For example, in the iris
data set:
head(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
Sepal.Length is a column/variable name that would often need backticks, while the Species setosa is character string value for the variable Species, and it would need quotation marks.
Let’s check out how some functions work with this.
In the tibble()
function when specifying names we need
to use backticks when we have spaces or punctuation or variable names
that are just numeric characters (this also works with single quotation
marks or double quotation marks, but backticks are more common
practice).
This is not required if we have a typical type of name without spaces or punctuation. However if we do use quotation marks on such a name is is not a problem either.
# the preferred method
ex_data <- tibble(
`Number!` = seq(from = 1, to = 5),
`Var with space` = c("A", "B", "C", "D", "E"),
`2022` = sample(seq(from = 1, to = 5), size = 5),
`2021` = sample(seq(from = 1, to = 5), size = 5),
typical = seq(from = 1, to = 5),
`typical2` = seq(from = 1, to = 5)
)
ex_data
## # A tibble: 5 × 6
## `Number!` `Var with space` `2022` `2021` typical typical2
## <int> <chr> <int> <int> <int> <int>
## 1 1 A 3 5 1 1
## 2 2 B 5 2 2 2
## 3 3 C 1 4 3 3
## 4 4 D 4 1 4 4
## 5 5 E 2 3 5 5
# this works
ex_data <- tibble(
"Number!" = seq(from = 1, to = 5),
"Var with space" = c("A", "B", "C", "D", "E"),
"2022" = sample(seq(from = 1, to = 5), size = 5),
"2021" = sample(seq(from = 1, to = 5), size = 5),
typical = seq(from = 1, to = 5),
"typical2" = seq(from = 1, to = 5)
)
ex_data
## # A tibble: 5 × 6
## `Number!` `Var with space` `2022` `2021` typical typical2
## <int> <chr> <int> <int> <int> <int>
## 1 1 A 4 3 1 1
## 2 2 B 1 5 2 2
## 3 3 C 2 2 3 3
## 4 4 D 3 4 4 4
## 5 5 E 5 1 5 5
rename()
We suggest that you avoid nonstandard variable names
No quotation marks or backticks are required for standard names
backticks are typically for nonstandard variable names (aka column names):
name with space
name!
12
1name
single or double quotation marks are typically used for character strings for the values within the data
No quotation marks are backticks are required for standard names. Underscores are OK for standard names:
iris %>%
rename(Sepal_Length = Sepal.Length) %>%
head()
## Sepal_Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
Here is an example with nonstandard names:
ex_data %>%
rename(Number = `Number!`)
## # A tibble: 5 × 6
## Number `Var with space` `2022` `2021` typical typical2
## <int> <chr> <int> <int> <int> <int>
## 1 1 A 4 3 1 1
## 2 2 B 1 5 2 2
## 3 3 C 2 2 3 3
## 4 4 D 3 4 4 4
## 5 5 E 5 1 5 5
ex_data %>%
rename(Number = "Number!")
## # A tibble: 5 × 6
## Number `Var with space` `2022` `2021` typical typical2
## <int> <chr> <int> <int> <int> <int>
## 1 1 A 4 3 1 1
## 2 2 B 1 5 2 2
## 3 3 C 2 2 3 3
## 4 4 D 3 4 4 4
## 5 5 E 5 1 5 5
# not necessary but not problematic to put new typical name in quotation marks
ex_data %>%
rename("Number" = "Number!")
## # A tibble: 5 × 6
## Number `Var with space` `2022` `2021` typical typical2
## <int> <chr> <int> <int> <int> <int>
## 1 1 A 4 3 1 1
## 2 2 B 1 5 2 2
## 3 3 C 2 2 3 3
## 4 4 D 3 4 4 4
## 5 5 E 5 1 5 5
Here is another example…
# This works because Sepal.Length already exists as a column name. However `new name!` needs backticks because it doesn't exist yet and R needs to know what it is (not a not equal to conditional for example), as R could interpret it differently.
iris %>%
rename(`new name!` = Sepal.Length) %>%
head()
## new name! Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
filter()
It is best to avoid using quotation marks for column names!
Even though this is an atypical column name, this will not work like you would expect.
Here we see values less than 5 for Sepal.Length
.
filter(iris, "Sepal.Length" > 5) %>% head()
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
Instead stick to just using the column name as it is - filter only works on columns that already exists, so it knows what to look for.
This works!
filter(iris, Sepal.Length > 5) %>% head()
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 5.4 3.9 1.7 0.4 setosa
## 3 5.4 3.7 1.5 0.2 setosa
## 4 5.8 4.0 1.2 0.2 setosa
## 5 5.7 4.4 1.5 0.4 setosa
## 6 5.4 3.9 1.3 0.4 setosa
summarize()
Only backticks will work here. Otherwise, the variable gets interpreted as a character string if we use quotation marks.
ex_data %>%
summarize(mean = mean(`2022`))
## # A tibble: 1 × 1
## mean
## <dbl>
## 1 3
# will not work
ex_data %>%
summarize(mean = mean("2022"))
## Warning: There was 1 warning in `summarize()`.
## ℹ In argument: `mean = mean("2022")`.
## Caused by warning in `mean.default()`:
## ! argument is not numeric or logical: returning NA
## # A tibble: 1 × 1
## mean
## <dbl>
## 1 NA
# will not work
ex_data %>%
summarize(mean = mean("Number!"))
## Warning: There was 1 warning in `summarize()`.
## ℹ In argument: `mean = mean("Number!")`.
## Caused by warning in `mean.default()`:
## ! argument is not numeric or logical: returning NA
## # A tibble: 1 × 1
## mean
## <dbl>
## 1 NA
mutate()
Only these work…
ex_data %>% mutate(`Number!` = `Number!` + 2)
## # A tibble: 5 × 6
## `Number!` `Var with space` `2022` `2021` typical typical2
## <dbl> <chr> <int> <int> <int> <int>
## 1 3 A 4 3 1 1
## 2 4 B 1 5 2 2
## 3 5 C 2 2 3 3
## 4 6 D 3 4 4 4
## 5 7 E 5 1 5 5
ex_data %>% mutate("Number!" = `Number!` + 2)
## # A tibble: 5 × 6
## `Number!` `Var with space` `2022` `2021` typical typical2
## <dbl> <chr> <int> <int> <int> <int>
## 1 3 A 4 3 1 1
## 2 4 B 1 5 2 2
## 3 5 C 2 2 3 3
## 4 6 D 3 4 4 4
## 5 7 E 5 1 5 5
ex_data %>% mutate(Typical = `Number!` + 2)
## # A tibble: 5 × 7
## `Number!` `Var with space` `2022` `2021` typical typical2 Typical
## <int> <chr> <int> <int> <int> <int> <dbl>
## 1 1 A 4 3 1 1 3
## 2 2 B 1 5 2 2 4
## 3 3 C 2 2 3 3 5
## 4 4 D 3 4 4 4 6
## 5 5 E 5 1 5 5 7
readr
functionsThe readr
package expects quotation marks not
backticks.
This is true for URLs or paths.
# Use this
vacc <- read_csv(file = "http://jhudatascience.org/intro_to_r/data/vaccinations.csv")
contains()
These require quotation marks.
select(iris, contains("et")) %>% head(n = 2)
## Petal.Length Petal.Width
## 1 1.4 0.2
## 2 1.4 0.2
select(iris, ends_with("Width")) %>% head(n = 2)
## Sepal.Width Petal.Width
## 1 3.5 0.2
## 2 3.0 0.2
recode()
Don’t need quotation marks for existing values.
ToothGrowth %>%
mutate(supp = recode(supp,
VC = "Ascorbic_Acid",
OJ = "Orange_juice"
)) %>%
count(supp)
## supp n
## 1 Orange_juice 30
## 2 Ascorbic_Acid 30
However it tolerates this.
ToothGrowth %>%
mutate(supp = recode(supp,
"VC" = "Ascorbic_Acid",
"OJ" = "Orange_juice"
)) %>%
count(supp)
## supp n
## 1 Orange_juice 30
## 2 Ascorbic_Acid 30
Backticks or quotation marks work for atypical column names.
ToothGrowth %>%
mutate(supp = paste0(supp, "!")) %>% # making atypical
mutate(supp = recode(supp,
`VC!` = "Ascorbic_Acid",
`OJ!` = "Orange_juice"
)) %>%
count(supp)
## supp n
## 1 Ascorbic_Acid 30
## 2 Orange_juice 30
ToothGrowth %>%
mutate(supp = paste0(supp, "!")) %>% # making atypical
mutate(supp = recode(supp,
"VC!" = "Ascorbic_Acid",
"OJ!" = "Orange_juice"
)) %>%
count(supp)
## supp n
## 1 Ascorbic_Acid 30
## 2 Orange_juice 30
separate
and unite
Here we have a very simple dataset. We are separating values based on the ‘.’ character.
df <- tibble(x = c(NA, "x.y", "x.z", "y.z"))
df
## # A tibble: 4 × 1
## x
## <chr>
## 1 <NA>
## 2 x.y
## 3 x.z
## 4 y.z
When naming the column to separate (x
), quotation marks
are optional. Use backticks if atypical.
df %>% separate(x, into = c("A", "B"))
## # A tibble: 4 × 2
## A B
## <chr> <chr>
## 1 <NA> <NA>
## 2 x y
## 3 x z
## 4 y z
df %>% separate("x", into = c("A", "B"))
## # A tibble: 4 × 2
## A B
## <chr> <chr>
## 1 <NA> <NA>
## 2 x y
## 3 x z
## 4 y z
However, note that the values supplied for into
and
sep
arguments must be in quotation marks.
# Will not work
df %>% separate(x, into = c(A, B))
## Error: object 'A' not found
unite
is easier. Quotation marks are optional for the
new column which you are creating (new_column
). Backticks
are required if atypical.
df2<- df %>% separate(x, into = c("A", "B"))
df2 %>% unite("new_column", A:B, remove = FALSE)
## # A tibble: 4 × 3
## new_column A B
## <chr> <chr> <chr>
## 1 NA_NA <NA> <NA>
## 2 x_y x y
## 3 x_z x z
## 4 y_z y z
df2 %>% unite(new_column, A:B, remove = FALSE)
## # A tibble: 4 × 3
## new_column A B
## <chr> <chr> <chr>
## 1 NA_NA <NA> <NA>
## 2 x_y x y
## 3 x_z x z
## 4 y_z y z
They are also optional for the columns you’re uniting together to
form the new column (A:B
). Backticks are required if
atypical.
df2 %>% unite(new_column, A:B, remove = FALSE)
## # A tibble: 4 × 3
## new_column A B
## <chr> <chr> <chr>
## 1 NA_NA <NA> <NA>
## 2 x_y x y
## 3 x_z x z
## 4 y_z y z
df2 %>% unite(new_column, "A":"B", remove = FALSE)
## # A tibble: 4 × 3
## new_column A B
## <chr> <chr> <chr>
## 1 NA_NA <NA> <NA>
## 2 x_y x y
## 3 x_z x z
## 4 y_z y z
case_when()
Need quotation marks for conditionals and new values.
ToothGrowth %>%
mutate(supp = case_when(
supp == "VC" ~ "Ascorbic_Acid",
supp == "OJ" ~ "Orange_juice"
)) %>%
count(supp)
## supp n
## 1 Ascorbic_Acid 30
## 2 Orange_juice 30
Only quotation marks work for atypical values. Backticks do not.
ToothGrowth %>%
mutate(supp = paste0(supp, "!")) %>% # making atypical
mutate(supp = case_when(
supp == "VC!" ~ "Ascorbic_Acid",
supp == "OJ!" ~ "Orange_juice"
)) %>%
count(supp)
## supp n
## 1 Ascorbic_Acid 30
## 2 Orange_juice 30
stringr
functionsWhen working with strings we need to use quotation marks.
x <- c("cat", "dog", "mouse")
# this will not work:
# x <- c(`cat`, `dog`, `mouse`)
When looking for patterns we need to use quotation marks because we are using it as a character string and quotation marks designate this. Backticks will not work.
x <- c("cat", "dog", "mouse")
# this will not work:
# x <- c(`cat`, `dog`, `mouse`)
str_detect(pattern = "t", string = x)
## [1] TRUE FALSE FALSE
# this will not work:
# str_detect(pattern = `t`, string = x)
join
functionsBy default, joins don’t use column names. The two supplied data objects are not in quotation marks:
band_members %>% inner_join(band_instruments)
## Joining with `by = join_by(name)`
## # A tibble: 2 × 3
## name band plays
## <chr> <chr> <chr>
## 1 John Beatles guitar
## 2 Paul Beatles bass
If you supply the by =
argument, you can use no
quotation marks, quotation marks, or backticks.
band_members %>% inner_join(band_instruments, by = join_by(name))
## # A tibble: 2 × 3
## name band plays
## <chr> <chr> <chr>
## 1 John Beatles guitar
## 2 Paul Beatles bass
band_members %>% inner_join(band_instruments, by = join_by("name"))
## # A tibble: 2 × 3
## name band plays
## <chr> <chr> <chr>
## 1 John Beatles guitar
## 2 Paul Beatles bass
band_members %>% inner_join(band_instruments, by = join_by(`name`))
## # A tibble: 2 × 3
## name band plays
## <chr> <chr> <chr>
## 1 John Beatles guitar
## 2 Paul Beatles bass
Use backticks if the column name is atypical.
band_instruments_2 <- rename(band_instruments, `1.name` = name)
band_members %>% inner_join(band_instruments_2, by = join_by(name == `1.name`))
## # A tibble: 2 × 3
## name band plays
## <chr> <chr> <chr>
## 1 John Beatles guitar
## 2 Paul Beatles bass
pivot_longer
and pivot_wider
These functions are a bit trickier because they have multiple arguments.
It is okay if the columns you are pivoting are without quotation
marks, with quotation marks, or with backticks. See
religion
in the example below. Here, the exclamation point
is not part of the column name, but rather indicating negation (all
columns except religion).
# These work!
relig_income %>%
pivot_longer(!religion, names_to = "income", values_to = "count")
## # A tibble: 180 × 3
## religion income count
## <chr> <chr> <dbl>
## 1 Agnostic <$10k 27
## 2 Agnostic $10-20k 34
## 3 Agnostic $20-30k 60
## 4 Agnostic $30-40k 81
## 5 Agnostic $40-50k 76
## 6 Agnostic $50-75k 137
## 7 Agnostic $75-100k 122
## 8 Agnostic $100-150k 109
## 9 Agnostic >150k 84
## 10 Agnostic Don't know/refused 96
## # ℹ 170 more rows
relig_income %>%
pivot_longer(!"religion", names_to = "income", values_to = "count")
## # A tibble: 180 × 3
## religion income count
## <chr> <chr> <dbl>
## 1 Agnostic <$10k 27
## 2 Agnostic $10-20k 34
## 3 Agnostic $20-30k 60
## 4 Agnostic $30-40k 81
## 5 Agnostic $40-50k 76
## 6 Agnostic $50-75k 137
## 7 Agnostic $75-100k 122
## 8 Agnostic $100-150k 109
## 9 Agnostic >150k 84
## 10 Agnostic Don't know/refused 96
## # ℹ 170 more rows
relig_income %>%
pivot_longer(!`religion`, names_to = "income", values_to = "count")
## # A tibble: 180 × 3
## religion income count
## <chr> <chr> <dbl>
## 1 Agnostic <$10k 27
## 2 Agnostic $10-20k 34
## 3 Agnostic $20-30k 60
## 4 Agnostic $30-40k 81
## 5 Agnostic $40-50k 76
## 6 Agnostic $50-75k 137
## 7 Agnostic $75-100k 122
## 8 Agnostic $100-150k 109
## 9 Agnostic >150k 84
## 10 Agnostic Don't know/refused 96
## # ℹ 170 more rows
# Use backticks if atypical
relig_income %>%
pivot_longer(c(`$10-20k`, `<$10k`), names_to = "income", values_to = "count")
## # A tibble: 36 × 11
## religion `$20-30k` `$30-40k` `$40-50k` `$50-75k` `$75-100k` `$100-150k`
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Agnostic 60 81 76 137 122 109
## 2 Agnostic 60 81 76 137 122 109
## 3 Atheist 37 52 35 70 73 59
## 4 Atheist 37 52 35 70 73 59
## 5 Buddhist 30 34 33 58 62 39
## 6 Buddhist 30 34 33 58 62 39
## 7 Catholic 732 670 638 1116 949 792
## 8 Catholic 732 670 638 1116 949 792
## 9 Don’t know/re… 15 11 10 35 21 17
## 10 Don’t know/re… 15 11 10 35 21 17
## # ℹ 26 more rows
## # ℹ 4 more variables: `>150k` <dbl>, `Don't know/refused` <dbl>, income <chr>,
## # count <dbl>
However, the new column names you are providing must be in
quotation marks. Here, these are supplied in the names_to
and values to
arguments. Pay attention to “income” and
“count”.
# This works
relig_income %>%
pivot_longer(!religion, names_to = "income", values_to = "count")
## # A tibble: 180 × 3
## religion income count
## <chr> <chr> <dbl>
## 1 Agnostic <$10k 27
## 2 Agnostic $10-20k 34
## 3 Agnostic $20-30k 60
## 4 Agnostic $30-40k 81
## 5 Agnostic $40-50k 76
## 6 Agnostic $50-75k 137
## 7 Agnostic $75-100k 122
## 8 Agnostic $100-150k 109
## 9 Agnostic >150k 84
## 10 Agnostic Don't know/refused 96
## # ℹ 170 more rows
# will not work
relig_income %>%
pivot_longer(!religion, names_to = income, values_to = count)
## Error: object 'income' not found
When using pivot_wider()
, quotation marks are optional
for the names_from
and values_from
arguments.
# These work!
fish_encounters %>%
pivot_wider(names_from = station, values_from = seen)
## # A tibble: 19 × 12
## fish Release I80_1 Lisbon Rstr Base_TD BCE BCW BCE2 BCW2 MAE MAW
## <fct> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
## 1 4842 1 1 1 1 1 1 1 1 1 1 1
## 2 4843 1 1 1 1 1 1 1 1 1 1 1
## 3 4844 1 1 1 1 1 1 1 1 1 1 1
## 4 4845 1 1 1 1 1 NA NA NA NA NA NA
## 5 4847 1 1 1 NA NA NA NA NA NA NA NA
## 6 4848 1 1 1 1 NA NA NA NA NA NA NA
## 7 4849 1 1 NA NA NA NA NA NA NA NA NA
## 8 4850 1 1 NA 1 1 1 1 NA NA NA NA
## 9 4851 1 1 NA NA NA NA NA NA NA NA NA
## 10 4854 1 1 NA NA NA NA NA NA NA NA NA
## 11 4855 1 1 1 1 1 NA NA NA NA NA NA
## 12 4857 1 1 1 1 1 1 1 1 1 NA NA
## 13 4858 1 1 1 1 1 1 1 1 1 1 1
## 14 4859 1 1 1 1 1 NA NA NA NA NA NA
## 15 4861 1 1 1 1 1 1 1 1 1 1 1
## 16 4862 1 1 1 1 1 1 1 1 1 NA NA
## 17 4863 1 1 NA NA NA NA NA NA NA NA NA
## 18 4864 1 1 NA NA NA NA NA NA NA NA NA
## 19 4865 1 1 1 NA NA NA NA NA NA NA NA
fish_encounters %>%
pivot_wider(names_from = "station", values_from = "seen")
## # A tibble: 19 × 12
## fish Release I80_1 Lisbon Rstr Base_TD BCE BCW BCE2 BCW2 MAE MAW
## <fct> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
## 1 4842 1 1 1 1 1 1 1 1 1 1 1
## 2 4843 1 1 1 1 1 1 1 1 1 1 1
## 3 4844 1 1 1 1 1 1 1 1 1 1 1
## 4 4845 1 1 1 1 1 NA NA NA NA NA NA
## 5 4847 1 1 1 NA NA NA NA NA NA NA NA
## 6 4848 1 1 1 1 NA NA NA NA NA NA NA
## 7 4849 1 1 NA NA NA NA NA NA NA NA NA
## 8 4850 1 1 NA 1 1 1 1 NA NA NA NA
## 9 4851 1 1 NA NA NA NA NA NA NA NA NA
## 10 4854 1 1 NA NA NA NA NA NA NA NA NA
## 11 4855 1 1 1 1 1 NA NA NA NA NA NA
## 12 4857 1 1 1 1 1 1 1 1 1 NA NA
## 13 4858 1 1 1 1 1 1 1 1 1 1 1
## 14 4859 1 1 1 1 1 NA NA NA NA NA NA
## 15 4861 1 1 1 1 1 1 1 1 1 1 1
## 16 4862 1 1 1 1 1 1 1 1 1 NA NA
## 17 4863 1 1 NA NA NA NA NA NA NA NA NA
## 18 4864 1 1 NA NA NA NA NA NA NA NA NA
## 19 4865 1 1 1 NA NA NA NA NA NA NA NA
glm()
You don’t need quotation marks for variables when modeling with
glm()
.
car_data <- mtcars
fit_cars <- glm(mpg ~ cyl + disp + hp + wt * gear, data = car_data)
Use backticks if there is an atypical name.
car_data <- rename(car_data, `mpg!` = mpg)
fit_cars <- glm(`mpg!` ~ cyl + disp + hp + wt * gear, data = car_data)
Do not use quotation marks.
# will not work
fit_cars <- glm("mpg!" ~ cyl + disp + hp + wt * gear, data = car_data)
## Error in terms.formula(formula, data = data): invalid term in model formula