I am trying to make a script to allows user to decide what column will be chosen for the graph (slope, r - value, p - value, ect.). However I am having trouble. I know that when I read it in, the data type is a string. How do i convert it to a compatible type so I can use it as a column name? Here is an example of the script:
print("State the file name (include .csv)")
filename <- readline()
file <- read.csv(filename)
print("State the variable to be plotted")
var <- readline()
hist(file$var)
Use
y = data[, "colname"]
to extract 'colname' variable into a vector y (Don't forget the comma).
Or you can use
y = data[["colname"]]
Or even using backtick quotes
col.name = "colname"
y = data[`col.name`]
Your code:
filename = readline()
data = read.csv(filename)
colname = readline()
hist(data[, colname])
Related
I have written a small function to write out a data frame to Stata .dta format.
dta <- function(data.in = dat){
haven::write_dta(data.in, here("Analysis", "data", "datasets", "stata_dat.dta"), version = 14)
}
What I would like to do though is to have a data.out argument so that I can specify a name rather than stata_dat.dta, in the event I want to write out multiple dataframes. How do I do this when the data.out argument also needs to be a string in the object save path?
#MrFlick the comment is great.
An alternative would be using
deparse(substitute())
dta <- function(data.in = dat, data.out=out.dta){
outname=deparse(substitute(data.out))
haven::write_dta(data.in, here("Analysis", "data", "datasets", outname), version = 14)
}
I am trying to automate the naming of a ggplot output saved using ggsave()
When I create the following plot I am able to retrieve the name of the plot using a combination of the deparse and substitute functions if I state the plot name explicitly
# make the plot
df <- data.frame(x = 1:10, y = 1:10)
my_plot <- ggplot(df, aes(x, y))+geom_point()
# generate the file name
filename <- paste0(deparse(substitute(my_plot)), ".jpg")
filename
However, I am trying to pass the plot name to the substitute function directly using without having to state it twice using .Last.value. This generates the incorrect result.
my_plot_name <- deparse(substitute(.Last.value))
my_plot_name
## [1] ".Last.value"
How can I access the name of the last ggplot object (or any other object) to be saved without stating the name explicitly?
EDIT: To be specific, my desired output based on the above example and some pseudo code would look like this:
filename <- paste0(deparse(substitute(.Last.value)), ".jpg")
filename
## [1] "my_plot.jpg"
You should be able to get it directly from the filename you're creating:
my_plot_name <- tools::file_path_sans_ext(filename)
my_plot_name
## [1] "my_plot"
Updated after edits:
.Last.value will only store the value, not the name of the variable that the value is being assigned into. First idea I'd have otherwise would be to check the names of variables in the environment to find which is equal to .Last.value. It seems to work in this simple case of your example:
my_plot <- ggplot(df, aes(x, y))+geom_point()
filename <- paste0(Filter(function(i) identical(get(i), .Last.value), ls()), ".jpg")
filename
## [1] "my_plot.jpg"
I have a few data frames (colors, sets, inventory) and I want to save each of them into a folder that I have set as my wd. I want to do this using a for loop, but I am not sure how to write the file argument such that R understands that it should use the elements of the vector as the file names.
I might write:
DFs <- c("colors", "sets", "inventory")
for (x in 1:length(DFs)){
save(x, file = "x.Rda")
}
The goal would be that the files would save as colors.Rda, sets.Rda, etc. However, the last element to run through the loop simply saves as x.Rda.
In short, perhaps my question is: how do you tell R that I am wanting to use elements being run through a loop within an argument when that argument requires a character string?
For bonus points, I am sure I will encounter the same problem if I want to load a series of files from that folder in the future. Rather than loading each one individually, I'd also like to write a for loop. To load these a few minutes ago, I used the incredibly clunky code:
sets_file <- "~/Documents/ME teaching/R notes/datasets/sets.csv"
sets <- read.csv(sets_file)
inventories_file <- "~/Documents/ME teaching/R notes/datasets/inventories.csv"
inventories <- read.csv(inventories_file)
colors_file <- "~/Documents/ME teaching/R notes/datasets/colors.csv"
colors <- read.csv(colors_file)
For compactness I use lapply instead of a for loop here, but the idea is the same:
lapply(DFs, \(x) save(list=x, file=paste0(x, ".Rda"))))
Note that you need to generate the varying file names by providing x as a variable and not as a character (as part of the file name).
To load those files, you can simply do:
lapply(paste0(DFs, ".Rda"), load, envir = globalenv())
To save you can do this:
DFs <- list(color, sets, inventory)
names(DFs) = c("color", "sets", "inventory")
for (x in 1:length(DFs)){
dx = paste(names(DFs)[[x]], "Rda", sep = ".")
dfx = DFs[[x]]
save(dfx, file = dx)
}
To specify the path just inform in the construction of the dx object as following to read.
To read:
DFs <- c("colors", "sets", "inventory")
# or
DFs = dir("~/Documents/ME teaching/R notes/datasets/")
for(x in 1:length(DFs)){
arq = paste("~/Documents/ME teaching/R notes/datasets/", DFs[x], ".csv", sep = "")
DFs[x] = read.csv(arq)
}
It will read as a list, so you can access using [[]] indexation.
I have a script where I read rasters from .asc files, e.g.:
# Read raster
raster <- brick('directory/subdirectory/file_a.asc', varname = 'man')
Now I want to replace the filename in the path (file_a.asc) by a string variable, so that I can change the file that I am reading once in the beginning of the code, instead of everywhere in the code where that specific file is read.
So for example:
# Define string variable, containing the name of the file that I want to read
var = 'file_a.asc'
raster <- brick('directory/subdirectory/**var**', varname = 'man')
Of course this doesn't work, but hopefully it illustrates what I want to do. I don't really know in which direction to look, maybe something with 'merge'?
You can simply do:
var <- 'file_a.asc'
raster <- brick(paste0("'directory/subdirectory/", var, "'"), varname = 'man')
Thanks Roland for suggesting the 'sprintf' function, exactly what I was looking for.
var <- 'file_a.asc'
raster <- brick(sprintf('directory/subdirectory/%s', var) , varname = 'man')
I have a function that takes a call xm, where xm is a learnt machine learning model. Is there a way tht within the function I can print the name of xm rather than the summary of the model which is what happens when you print(xm)
For example, my function generates graphs that I am saving within the function
modsummary <- function(xm){
mypath <- file.path("C:","Users","Documents",paste("rf_fit_hmeas_random", ".png", sep = ""))
png(file = mypath)
print(plot(xm))
dev.off()
}
modsummary(rf_fit)
What I am trying to do is set this up in way so that it will paste xm (in this case rf_fit) so that it automatically detecs the function called and replaces xm_hmeas_random each time a different model is called.
Thank you
Yes, you can use deparse(substitute(xm)) to get this.
So it would be..
modsummary <- function(xm){
mypath <- file.path("C:/","Users/","Documents/",paste0(deparse(substitute(xm)), "_hmeas_random.png"))
png(file = mypath)
print(plot(xm))
dev.off()
}
modsummary(rf_fit)
I've added in the slashes (/) between your directory names and switched to using paste0() which negates the need to specify a separator.