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())
Related
I need specific files from "global environment" to run some calculations for each file
I have 390 data files with nearly the same structure in the global environment
and i need to take 330 specific files.
So I ran a for-loop to compare the elements from the global environment with a list that contains
the elements names I need to take.
For each file I need to transform a factor variable into dummy-coding.
The for-loop is the following:
for(x in t(upc.unique))
{
xName <- paste(x,"csv", sep = ".")
for(y in tmp) #tmp equals the elements of the global environment
{
as.character(tmp)
if (xName == y)
{ as.list(tmp)
assign(tmp[i], paste(tmp[i],"d")<-cbind(tmp[i], model.matrix(~factor(tmp[i]$SALES) - 1)))
}
}
}
"upc.unique" contains the names of the data files I need to pick from the global environment
"tmp" is a large list of each element of the "global environment"
My question is if there's a better and faster way to do the task.
Im pretty sure that there is a way, but because I am new with R, it is hard for me to find it.
I have created a list of objects in my work environment
data <- c("variable1", "variable2", "variable3")
i would like to save the files to different directories with the variable name as the directory... so i did this to give me a list of file names to pass to the save function via lapply..
paste0(data,"/",data,".rda")
lapply(data,FUN=save,file = paste0(data,"/",data,".rda"))
i get the error
Error in FUN(X[[i]], ...) : object ‘X[[i]]’ not found
i'm not sure what i'm doing wrong here..
Do you have a list of objects, or a list of names of objects? You say you have the former, but the code you give is for the latter.
Also, if you only have one object per file, then it's better to use the saveRDS function (and loadRDS to load it).
lapply(data, function(x) saveRDS(get(x), paste0(x, "/", x, ".rds")))
If you have to use save:
lapply(data, function(x) save(list=x, file=paste0(x, "/", x, ".rds")))
Several things going on here.
First, you need not use lapply when you don't care about the return value of the function called at each iteration. It offers nothing in this case.
Second, and more importantly, what you are doing is writing objects to files with names derived from their variable names in R. That's an anti-pattern.
Instead, create a list of the objects, and use for for the work. We need to use saveRDS for this (thanks Hong Ooi) as l[[n]] is also not the name of an object in the environment.
l <- list(variable1 = variable1, variable2 = variable2, variable3=variable3)
for (n in names(l)) {
fname = paste0(n, '/', n, '.rda')
saveRDS(file=fname, l[[n]])
}
It would be better to just save the entire list, but then all the data would be in one file in one directory.
As for what's actually wrong with your code:
You pass the same value for file to all invocations of save, and you don't intend to do so. This value is a vector, but what you want is that each iteration gets one element from this vector.
The way lapply computes the value to pass to the function confuses save. In particular, it does this:
names <- as.character(substitute(list(...)))[-1L]
That results in something like the following, which is not the name of an object in the environment.
c("variable1", "variable2", "variable3")[[1]]
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 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"))
}
})
})
I am trying to source multiple functions, that differ by a number in the name.
For example: func1, func2.
I tried using "func_1", and "func_2", as well as putting the number first, "1func" and "2func". No matter how I index the function names, the source function just reads in one function that it calls "func" - which is not what I want.
I have tried using for-loops and sapply:
for-loop:
func.list <- list.files(path="/some_path",pattern="some pattern",full.names=TRUE)
for(i in 1:length(func.list)){
source(func.list[i])
}
sapply:
sapply(func.list,FUN=source)
I am going to be writing multiple versions of a data correction function, and would really like to be able to index them - because giving a concise, but specific, name would be difficult, and not allow me to selectively source just the function files from their directory.
In my code, func.list gives the output (I have replaced the actual directory because of privacy/contractual issues):
[1] "mypath/1resp.correction.R"
[2] "mypath/2resp.correction.R"
Then when I source func.list with either the for-loop or sapply code (listed above), R only loads one function named resp.correction, with the code body from "2resp.correction.R".
The argument to source is a file name, not a function name. So you cannot be fancy here: you need to provide the exact filenames.
It sounds like your two files contain the definitions of a function with the same name (resp.correction) in both files, so yes, as you source one file after the other, the function is overwritten in your global environment.
You could, inside your loop, reassign the function to a different name:
func.list <- list.files(path="/some_path",pattern="some pattern",full.names=TRUE)
for(i in 1:length(func.list)) {
source(func.list[i], local = TRUE)
assign(paste0("resp.correction", i), resp.correction, envir = .GlobalEnv)
}