I have several data.frames in an environment which I would like to save into separate .RData files. Is there a function which is able to save to whole workspace?
I usually just do this with the following function:
save(x, file = "xy.RData")
but is there a way I could save all the data.frames separately at once?
Creating a bunch of different files isn't how save() is vectorized. Probably better to use a loop here. First, get a vector of all of your data.frame names.
dfs<-Filter(function(x) is.data.frame(get(x)) , ls())
Now write each to a file.
for(d in dfs) {
save(list=d, file=paste0(d, ".RData"))
}
Or if you just wanted them all in one file
save(list=dfs, file="alldfs.RData")
To save your workspace you just need to do:
save.image("willcontainworkspace.RData")
This creates a single file that contains the entire workspace which may or may not be what you want but your question wasn't completely clear to me.
Similar to #MrFlick's approach, you can do something like this:
invisible({
sapply(ls(envir = .GlobalEnv), function(x) {
obj <- get(x, envir = .GlobalEnv)
if (class(obj) == "data.frame") {
save(obj, file = paste0(x, ".RData"))
}
})
})
Related
I have a directory with .docx files that I want to import via textreadr's read_docx function.
First I set the working directory and create list of files:
setwd("C:/R")
files <- list.files("C:/R", pattern = "\\.docx")
Now I want to iterate through the list and import every file individually, named data_"file":
for (file in files) {
assign("data_", file, sep = "") <- read_docx("file")
}
Optionally, I tried creating a list of lists:
data_list <- lapply(files, function(v){
read_docx("v")
})
Both variants don't work and I'm not sure what I do wrong.
Maybe the full path is not present, we can add
files <- list.files("C:/R", pattern = "\\.docx", full.names = TRUE)
The issue is that v or file is quoted i.e. "" i.e. it is trying to read a string "v" instead of the value. Thus, the code in the OP's post can be corrected to
data_list <- lapply(files, function(v){
read_docx(v)
})
or in the for loop
for (file in files) {
assign(paste0("data_", file, sep = ""), read_docx(file))
}
Also, as noted in the comments, if there are 1000 files, assign creates 1000 new objects which is a bit messy when we want to gather all of them again. Instead, as in the lapply, which creates a single list, the output from for loop can be store in a list
data_list2 <- vector('list', length(files))
names(data_list2) <- files
for(file in files) {
data_list2[[file]] <- read_docx(file)
}
First off, you need to grab the full path instead of just the filenames from list.files:
files <- list.files("C:/R", pattern = "\\.docx$", full.names = TRUE)
Then the lapply solution works if you pass the parameter v to read_docx instead of a literal string "v". You don’t even need the nested function:
data_list <- lapply(files, read_docx)
As an aside, there’s no need for setwd in your code, and its use is strongly discouraged.
Furthermore, using the assign function as in your code doesn’t work and even after fixing the syntax, this use is simply completely inappropriate: at best it is a hack that approximates the functionality of lists, but badly. The correct solution, 10 times out of 10, is to use a named list or vector in its place.
I need to read several csv files from a directory and save each data in separate dataframe.
The filenames are in a character vector:
lcl_forecast_data_files <- dir(lcl_forecast_data_path, pattern=glob2rx("*.csv"), full.names=TRUE)
For example: "fruc2021.csv", "gem2020.csv", "strb2021.csv".
So far I am reading the files step by step:
fruc2021 <- read_csv2("fruc2021.csv")
gem2020 <- read_csv2("gem2020.csv")
strb2010 <- read_csv2("strb2021.csv")
But there are many more files in the directory and subdirectories. To read them all one by one is very tedious.
Now I have already experimented a little with the map function, but I have not yet figured out how to automatically generate the names of the dataframes from the file names.
A first simple try was:
lcl_forecast_data <- lcl_forecast_data_files %>%
map(
function(x) {
str_replace(basename(x), ".csv","") <- read_csv2(x)
}
)
But this did not work :-(
Is it even possible to generate names for dataframes like this?
Or are there other, simpler possibilities?
Greetings
Benne
Translated with www.DeepL.com/Translator (free version)
If you do not want to use a list and lapply as #Onyambu suggested you can use assign() to generate the dataframes.
filenames <- c("fruc2021.csv", "gem2020.csv", "strb2021.csv")
for (i in filenames) {
assign(paste('',gsub(".csv","",i),sep=''),read.csv(i))
}
I have a bunch of .gpx files in a folder and I'm trying to read them all with readOGR and get one file in memory for each .gpx file. Here's what isn't working:
myfiles <- list.files(".", pattern = "*.gpx")
for (i in 1:length(myfiles)) {
temp.gpx <- readOGR(dsn = myfiles[i], layer="tracks")
temp.gpx
}
What this does is read all of the files and then write them to temp.gpx. What I'd like this to do is to read them and write them to, e.g., temp1.gpx, temp2.gpx, etc.
Unfortunately, I'm pretty new to R and I've no idea how to do it. I tried looking online and found some solutions that were specific to non-spatial files and messed up these files in one way or another.
Does anyone know how to accomplish this?
Thanks!
You can use assign() to generate variable names using other variables:
myfiles <- list.files(".",pattern = "*.gpx")
for (i in 1:length(myfiles)) {
varName <- paste0("temp", i, ".gpx")
assign(varName, readOGR(dsn = myfiles[i], layer="tracks"))
}
This will create a character variable varName with each iteration of the loop which will have the value temp1.gpx, temp2.gpx, etc:
## i <- 1
varName <- paste0("temp", i, ".gpx")
## [1] "temp1.gpx"
The assign() then assigns the result of readOGR() to the current temp*.gpx variable.
The use of assign is in most cases a very poor choice. Although Stuart Allen answered your question correctly, your are most likely asking the wrong question.
What you are trying to do is a typical beginners mistake. With this approach you end up with several named objects that are difficult to manipulate because you need to refer to them by their names, making it hard to use the objects in a loop, for example.
Instead you probably should make a list with all your objects:
gpx <- lapply(myfiles,
function(f) { readOGR(dsn=f, layer="tracks") }
)
And take it from there.
I need to save items in my environment in R to disk. I can't figure out why the following code doesn't work :
op <- function(){
for(i in 1:length(ls())){
file <- paste0(ls()[i],".Rds")
saveRDS(file,file)
}
}
There are actually couple things wrong here:
I suspect you want to save .GlobalEnv, not just op's environment. However the calls to ls will list objects in op's environment (which is only i by the time you call ls). If you want to list object in .GlobalEnv, call ls(.GlobalEnv)
Also, when you are calling saveRDS, you are telling it to save a string stored in file into path stored in file. So you are essentially only saving the path. Instead you need to get the object from .GlobalEnv
So one of correct ways to do it would be:
op <- function(){
obj_names <- ls(.GlobalEnv)
for(i in 1:length(obj_names){
file <- paste0(obj_names[i],".Rds")
saveRDS(get(obj_names[i], envir = .GlobalEnv), file)
}
}
Or a bit more idiomatic,
op <- function()
sapply(ls(.GlobalEnv), function(x) saveRDS(get(x, envir = .GlobalEnv), paste0(x, ".Rds"))
Also save function might be useful, if you don't mind saving all objects in one file. More at ?save
The code you wrote only saves a list of files with names identical to the names in the environment of your function (i.e. a single file "i.rds").
If you want to save the contents of an environment to a file, you might want to try the save() or save.image() function which does exactly what you are looking for.
For information try ?save. Here is some code:
a <- 1
b <- 2
save(list=ls(), file="myfile.rda")
rm(list=ls())
load(file="myfile.rda")
ls()
yielding:
[1] "a" "b"
I am new to R and trying to use file names as variable names in R.
Basically, I have a folder containing a list of files
and I want to load all files into R and use their names for variable names
for(i in list.files()) {
loaddata(i,i)
}
This does not work, I also tried as.name and paste, both don't work.
Can anyone please help?
Here's a one liner that'll get you most of the way:
sapply(list.files("~/r"), FUN = function(X) assign(X, rnorm(1)))
This assigns a random number to an object in the global environment, with each object taking its name from the files in my ~/r/ directory.
To give a concrete example, say we had a directory ~/r and we wished to read the files in and have them as seperate items in the environment -- then one would do the following:
list2env(sapply(list.files("~/r"), FUN = function(X) read.csv(X)), globalenv())
This is a combination of two commands that has the advantage of not cluttering the global environment with the list containing all the files.
In steps we would do:
inList <- sapply(list.files("~/r"), FUN = function(X) read.csv(X))
list2env(inList, globalenv())