I have a dataframe that I want to loop through some column (will vary in name) and build a string. This is simplified, but illustrates the approach:
library(tidyverse)
df_original <- data.frame(id = 1:3, string = c("dog", "cat", "mouse"))
df_original
> df_original
id string
1 1 dog
2 2 cat
3 3 mouse
# Easily can build string using base R with loop like this:
for (i in 1:nrow(df_original)){
print(paste("I love my pet", df_original[i, "string"]))
}
[1] "I love my pet dog"
[1] "I love my pet cat"
[1] "I love my pet mouse"
I want to put this in a function with the ability to map different column names to the data-variable. I was looking at "indirection", which I've used when writing function in DPLYR, but this doesn't work (and I expected that):
# Want to apply same idea inside function where df's column names may change,
# so I need to be able to quote them, but I know this is wrong.
myfun <- function(df, var){
for (i in 1:nrow(df)){
print(paste("I love my pet", df[i, {{var}}]))
}
}
# This fails:
myfun(df_original, string)
Error: object 'string' not found
I can rename()
(DPLYR verb) the dataframe at the start of the function -- as seen below -- and get where I want, but this is a fuzzy area of R for me, and I'm hoping someone can explain how I might achieve that result in base R. My actual use case (not this simplified example) has me building URL GET requests using lat/longs for origin/destination combinations, and the four columns are never consistently named in the source dataframes.
# Can rename the variable locally in the function, then use, but
# this seems clunky.
myfun2 <- function(df, var){
df <- rename(df, var = {{var}})
for (i in 1:nrow(df)){
print(paste("I love my pet", df[i, "var"]))
}
}
# But it does work:
myfun2(df_original, string)
> myfun2(df_original, string)
[1] "I love my pet dog"
[1] "I love my pet cat"
[1] "I love my pet mouse"
I appreciate any suggestions. Thank you.
myfun <- function(df, var){
paste("I love my pet", eval(substitute(var), df))
}
myfun(df_original, string)
[1] "I love my pet dog" "I love my pet cat" "I love my pet mouse"
myfun <- function(df, var){
paste("I love my pet", df[,deparse(substitute(var))])
}
myfun(df_original, string)
[1] "I love my pet dog" "I love my pet cat" "I love my pet mouse"
myfun <- function(df, var){
var <- deparse(substitute(string))
for (i in 1:nrow(df)){
print(paste("I love my pet", df[i, var]))
}
}
myfun(df_original, string)
[1] "I love my pet dog"
[1] "I love my pet cat"
[1] "I love my pet mouse"