G.Maubach at weinwolf.de
2016-Aug-16 06:43 UTC
[R] Antwort: Re: Accessing an object using a string
Hi Greg and all others who replied to my question, many thanks for all your answers and help. Currently I store all my objects in .GlobalEnv = Workspace. I am not yet familiar working with different environments nor did I see that this would be necessary for my analysis. Could you explain why working with different environments would be helpful? You suggested to read variables into lists rather than storing them in global variables. This sounds interesting. Could you provide an example of how to define and use this? Kind regards Georg Von: Greg Snow <538280 at gmail.com> An: G.Maubach at weinwolf.de, Kopie: r-help <r-help at r-project.org> Datum: 15.08.2016 20:33 Betreff: Re: [R] Accessing an object using a string The names function is a primitive, which means that if it does not already do what you want, it is generally not going to be easy to coerce it to do it. However, the names of an object are generally stored as an attribute of that object, which can be accessed using the attr or attributes functions. If you change your code to not use the names function and instead use attr or attributes to access the names then it should work for you. You may also want to consider changing your workflow to have your data objects read into a list rather than global variables, then process using lapply/sapply (this would require a change in how your data is saved from your example, but if you can change that then everything after can be cleaner/simpler/easier/more fool proof/etc.) On Mon, Aug 15, 2016 at 2:49 AM, <G.Maubach at weinwolf.de> wrote:> Hi All, > > I would like to access an object using a sting. > > # Create example dataset > var1 <- c(1, 2, 3) > var2 <- c(4, 5, 6) > data1 <- data.frame(var1, var2) > > var3 <- c(7, 8, 9) > var4 <- c(10, 11, 12) > data2 <- data.frame(var3, var4) > > save(file = "c:/temp/test.RData", list = c("data1", "data2")) > > # Define function > t_load_dataset <- function(file_path, > file_name) { > file_location <- file.path(file_path, file_name) > > print(paste0('Loading ', file_location, " ...")) > cat("\n") > > object_list <- load(file = file_location, > envir = .GlobalEnv) > > print(paste(length(object_list), "dataset(s) loaded from", > file_location)) > cat("\n") > > print("The following objects were loaded:") > print(object_list) > cat("\n") > > for (i in object_list) { > print(paste0("Object '", i, "' in '", file_name, "' contains:")) > str(i) > names(i) # does not work > } > } > > I have only the character vector object_list containing the names of the > objects as strings. I would like to access the objects in object_list to > be able to print the names of the variables within the object (usualllya> data frame). > > Is it possible to do this? How is it done? > > Kind regards > > Georg > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guidehttp://www.R-project.org/posting-guide.html> and provide commented, minimal, self-contained, reproducible code.-- Gregory (Greg) L. Snow Ph.D. 538280 at gmail.com
Interestingly I just gave a presentation on this last Friday. Using load it is a little more complicated since load reads the object name from the file as well (which can lead to overwriting objects if loading from more than one file). So it is better to use another save format if possible. One alternative is to use the saveRDS and readRDS functions. Here is the example that I presented: First, create some sample data files on the disk (here saving as .csv files) data('Oxboys', package='nlme') obl <- split(Oxboys, Oxboys$Subject) for(d in obl) { write.csv(d, file=sprintf("OxBoys%02d.csv", d$Subject[1]), row.names=FALSE) } rm(Oxboys,obl) Now read the files into R into a single list (and add names to the list, optional but can be nice): fnames <- list.files(pattern='^OxBoys') ob.new <- lapply(fnames, read.csv) nms <- paste0('OxBoys', sapply(ob.new, function(df) df$Subject[1])) names(ob.new) <- nms head( ob.new$OxBoys1 ) The list.files function in the first line is one convenient way to create the vector of filenames, but other options would include paste0, sprintf, and others. Now perform the same analysis on each data frame in the list and nicely format the results (a simple regression in this case): slopes <- sapply(ob.new, function(df) { fit <- lm(height~age, data=df) coef(fit) }) head(t(slopes)) On Tue, Aug 16, 2016 at 12:43 AM, <G.Maubach at weinwolf.de> wrote:> Hi Greg > and all others who replied to my question, > > many thanks for all your answers and help. Currently I store all my > objects in .GlobalEnv = Workspace. I am not yet familiar working with > different environments nor did I see that this would be necessary for my > analysis. > > Could you explain why working with different environments would be > helpful? > > You suggested to read variables into lists rather than storing them in > global variables. This sounds interesting. Could you provide an example of > how to define and use this? > > Kind regards > > Georg > > > > Von: Greg Snow <538280 at gmail.com> > An: G.Maubach at weinwolf.de, > Kopie: r-help <r-help at r-project.org> > Datum: 15.08.2016 20:33 > Betreff: Re: [R] Accessing an object using a string > > > > The names function is a primitive, which means that if it does not > already do what you want, it is generally not going to be easy to > coerce it to do it. > > However, the names of an object are generally stored as an attribute > of that object, which can be accessed using the attr or attributes > functions. If you change your code to not use the names function and > instead use attr or attributes to access the names then it should work > for you. > > > You may also want to consider changing your workflow to have your data > objects read into a list rather than global variables, then process > using lapply/sapply (this would require a change in how your data is > saved from your example, but if you can change that then everything > after can be cleaner/simpler/easier/more fool proof/etc.) > > > On Mon, Aug 15, 2016 at 2:49 AM, <G.Maubach at weinwolf.de> wrote: >> Hi All, >> >> I would like to access an object using a sting. >> >> # Create example dataset >> var1 <- c(1, 2, 3) >> var2 <- c(4, 5, 6) >> data1 <- data.frame(var1, var2) >> >> var3 <- c(7, 8, 9) >> var4 <- c(10, 11, 12) >> data2 <- data.frame(var3, var4) >> >> save(file = "c:/temp/test.RData", list = c("data1", "data2")) >> >> # Define function >> t_load_dataset <- function(file_path, >> file_name) { >> file_location <- file.path(file_path, file_name) >> >> print(paste0('Loading ', file_location, " ...")) >> cat("\n") >> >> object_list <- load(file = file_location, >> envir = .GlobalEnv) >> >> print(paste(length(object_list), "dataset(s) loaded from", >> file_location)) >> cat("\n") >> >> print("The following objects were loaded:") >> print(object_list) >> cat("\n") >> >> for (i in object_list) { >> print(paste0("Object '", i, "' in '", file_name, "' contains:")) >> str(i) >> names(i) # does not work >> } >> } >> >> I have only the character vector object_list containing the names of the >> objects as strings. I would like to access the objects in object_list to >> be able to print the names of the variables within the object (usuallly > a >> data frame). >> >> Is it possible to do this? How is it done? >> >> Kind regards >> >> Georg >> >> ______________________________________________ >> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code. > > > > -- > Gregory (Greg) L. Snow Ph.D. > 538280 at gmail.com > >-- Gregory (Greg) L. Snow Ph.D. 538280 at gmail.com
Inline. Bert Gunter "The trouble with having an open mind is that people keep coming along and sticking things into it." -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) On Mon, Aug 15, 2016 at 11:43 PM, <G.Maubach at weinwolf.de> wrote:> Hi Greg > and all others who replied to my question, > > many thanks for all your answers and help. Currently I store all my > objects in .GlobalEnv = Workspace. I am not yet familiar working with > different environments nor did I see that this would be necessary for my > analysis. > > Could you explain why working with different environments would be > helpful? > > You suggested to read variables into lists rather than storing them in > global variables. This sounds interesting. Could you provide an example of > how to define and use this?It sounds to me as if you really need to spend some time with an R tutorial or two before you do anything else. There are many good ones on the web. See here for some suggestions: https://www.rstudio.com/online-learning/#R While you may reasonably expect some help with R programming and related matters here, you should not expect this list to do your homework for you, at least IMHO (others may disagree). Cheers, Bert> > Kind regards > > Georg > > > > Von: Greg Snow <538280 at gmail.com> > An: G.Maubach at weinwolf.de, > Kopie: r-help <r-help at r-project.org> > Datum: 15.08.2016 20:33 > Betreff: Re: [R] Accessing an object using a string > > > > The names function is a primitive, which means that if it does not > already do what you want, it is generally not going to be easy to > coerce it to do it. > > However, the names of an object are generally stored as an attribute > of that object, which can be accessed using the attr or attributes > functions. If you change your code to not use the names function and > instead use attr or attributes to access the names then it should work > for you. > > > You may also want to consider changing your workflow to have your data > objects read into a list rather than global variables, then process > using lapply/sapply (this would require a change in how your data is > saved from your example, but if you can change that then everything > after can be cleaner/simpler/easier/more fool proof/etc.) > > > On Mon, Aug 15, 2016 at 2:49 AM, <G.Maubach at weinwolf.de> wrote: >> Hi All, >> >> I would like to access an object using a sting. >> >> # Create example dataset >> var1 <- c(1, 2, 3) >> var2 <- c(4, 5, 6) >> data1 <- data.frame(var1, var2) >> >> var3 <- c(7, 8, 9) >> var4 <- c(10, 11, 12) >> data2 <- data.frame(var3, var4) >> >> save(file = "c:/temp/test.RData", list = c("data1", "data2")) >> >> # Define function >> t_load_dataset <- function(file_path, >> file_name) { >> file_location <- file.path(file_path, file_name) >> >> print(paste0('Loading ', file_location, " ...")) >> cat("\n") >> >> object_list <- load(file = file_location, >> envir = .GlobalEnv) >> >> print(paste(length(object_list), "dataset(s) loaded from", >> file_location)) >> cat("\n") >> >> print("The following objects were loaded:") >> print(object_list) >> cat("\n") >> >> for (i in object_list) { >> print(paste0("Object '", i, "' in '", file_name, "' contains:")) >> str(i) >> names(i) # does not work >> } >> } >> >> I have only the character vector object_list containing the names of the >> objects as strings. I would like to access the objects in object_list to >> be able to print the names of the variables within the object (usuallly > a >> data frame). >> >> Is it possible to do this? How is it done? >> >> Kind regards >> >> Georg >> >> ______________________________________________ >> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide > http://www.R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code. > > > > -- > Gregory (Greg) L. Snow Ph.D. > 538280 at gmail.com > >
I'm surprised no one has given what I consider to be the standard answer to this questions, namely ?get. Won't for (i in object_list) { print(paste0("Object '", i, "' in '", file_name, "' contains:")) str(get(i)) print(names(get(i))) # works } do what you want? Best, Ista On Tue, Aug 16, 2016 at 11:46 AM, Greg Snow <538280 at gmail.com> wrote:> Interestingly I just gave a presentation on this last Friday. > > Using load it is a little more complicated since load reads the object > name from the file as well (which can lead to overwriting objects if > loading from more than one file). So it is better to use another save > format if possible. One alternative is to use the saveRDS and readRDS > functions. > > Here is the example that I presented: > > First, create some sample data files on the disk (here saving as .csv files) > > data('Oxboys', package='nlme') > obl <- split(Oxboys, Oxboys$Subject) > for(d in obl) { > write.csv(d, file=sprintf("OxBoys%02d.csv", > d$Subject[1]), > row.names=FALSE) > } > rm(Oxboys,obl) > > > Now read the files into R into a single list (and add names to the > list, optional but can be nice): > > fnames <- list.files(pattern='^OxBoys') > ob.new <- lapply(fnames, read.csv) > nms <- paste0('OxBoys', sapply(ob.new, > function(df) df$Subject[1])) > names(ob.new) <- nms > head( ob.new$OxBoys1 ) > > The list.files function in the first line is one convenient way to > create the vector of filenames, but other options would include > paste0, sprintf, and others. > > Now perform the same analysis on each data frame in the list and > nicely format the results (a simple regression in this case): > > slopes <- sapply(ob.new, function(df) { > fit <- lm(height~age, data=df) > coef(fit) > }) > head(t(slopes)) > > > > > On Tue, Aug 16, 2016 at 12:43 AM, <G.Maubach at weinwolf.de> wrote: >> Hi Greg >> and all others who replied to my question, >> >> many thanks for all your answers and help. Currently I store all my >> objects in .GlobalEnv = Workspace. I am not yet familiar working with >> different environments nor did I see that this would be necessary for my >> analysis. >> >> Could you explain why working with different environments would be >> helpful? >> >> You suggested to read variables into lists rather than storing them in >> global variables. This sounds interesting. Could you provide an example of >> how to define and use this? >> >> Kind regards >> >> Georg >> >> >> >> Von: Greg Snow <538280 at gmail.com> >> An: G.Maubach at weinwolf.de, >> Kopie: r-help <r-help at r-project.org> >> Datum: 15.08.2016 20:33 >> Betreff: Re: [R] Accessing an object using a string >> >> >> >> The names function is a primitive, which means that if it does not >> already do what you want, it is generally not going to be easy to >> coerce it to do it. >> >> However, the names of an object are generally stored as an attribute >> of that object, which can be accessed using the attr or attributes >> functions. If you change your code to not use the names function and >> instead use attr or attributes to access the names then it should work >> for you. >> >> >> You may also want to consider changing your workflow to have your data >> objects read into a list rather than global variables, then process >> using lapply/sapply (this would require a change in how your data is >> saved from your example, but if you can change that then everything >> after can be cleaner/simpler/easier/more fool proof/etc.) >> >> >> On Mon, Aug 15, 2016 at 2:49 AM, <G.Maubach at weinwolf.de> wrote: >>> Hi All, >>> >>> I would like to access an object using a sting. >>> >>> # Create example dataset >>> var1 <- c(1, 2, 3) >>> var2 <- c(4, 5, 6) >>> data1 <- data.frame(var1, var2) >>> >>> var3 <- c(7, 8, 9) >>> var4 <- c(10, 11, 12) >>> data2 <- data.frame(var3, var4) >>> >>> save(file = "c:/temp/test.RData", list = c("data1", "data2")) >>> >>> # Define function >>> t_load_dataset <- function(file_path, >>> file_name) { >>> file_location <- file.path(file_path, file_name) >>> >>> print(paste0('Loading ', file_location, " ...")) >>> cat("\n") >>> >>> object_list <- load(file = file_location, >>> envir = .GlobalEnv) >>> >>> print(paste(length(object_list), "dataset(s) loaded from", >>> file_location)) >>> cat("\n") >>> >>> print("The following objects were loaded:") >>> print(object_list) >>> cat("\n") >>> >>> for (i in object_list) { >>> print(paste0("Object '", i, "' in '", file_name, "' contains:")) >>> str(i) >>> names(i) # does not work >>> } >>> } >>> >>> I have only the character vector object_list containing the names of the >>> objects as strings. I would like to access the objects in object_list to >>> be able to print the names of the variables within the object (usuallly >> a >>> data frame). >>> >>> Is it possible to do this? How is it done? >>> >>> Kind regards >>> >>> Georg >>> >>> ______________________________________________ >>> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >>> https://stat.ethz.ch/mailman/listinfo/r-help >>> PLEASE do read the posting guide >> http://www.R-project.org/posting-guide.html >>> and provide commented, minimal, self-contained, reproducible code. >> >> >> >> -- >> Gregory (Greg) L. Snow Ph.D. >> 538280 at gmail.com >> >> > > > > -- > Gregory (Greg) L. Snow Ph.D. > 538280 at gmail.com > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.
My example shows that using a dedicated environment allows you to segregate the items loaded from the save file from the objects you are working with. It has the advantage that any kind of object or collection of objects can be loaded that way. It has the disadvantage that you have to keep track of what kinds of objects they are (as in not data frames). For example, suppose you want to make a data table that summarizes information about the contents of several save files. If you name the data frame you are building up "infodf" and one of the save files has a data frame by that name in it, then loading it into the global environment will wipe out the information so far accumulated and replace it with something else. Greg's option of saving individual objects into rds files is another solution. It has the advantage of letting you control the name of the imported object, but you still need to independently insure that the object is actually a data frame somehow before digging into its columns. Personally, I prefer to avoid keeping lots of rds or RData files around... I favor restarting from original input files to insure reproducibility. Any output values that I want to emit from my analysis I write into CSV or other portable format. I only use rds/RData files for temporary storage (caching) for performance acceleration. -- Sent from my phone. Please excuse my brevity. On August 15, 2016 11:43:14 PM PDT, G.Maubach at weinwolf.de wrote:>Hi Greg >and all others who replied to my question, > >many thanks for all your answers and help. Currently I store all my >objects in .GlobalEnv = Workspace. I am not yet familiar working with >different environments nor did I see that this would be necessary for >my >analysis. > >Could you explain why working with different environments would be >helpful? > >You suggested to read variables into lists rather than storing them in >global variables. This sounds interesting. Could you provide an example >of >how to define and use this? > >Kind regards > >Georg > > > >Von: Greg Snow <538280 at gmail.com> >An: G.Maubach at weinwolf.de, >Kopie: r-help <r-help at r-project.org> >Datum: 15.08.2016 20:33 >Betreff: Re: [R] Accessing an object using a string > > > >The names function is a primitive, which means that if it does not >already do what you want, it is generally not going to be easy to >coerce it to do it. > >However, the names of an object are generally stored as an attribute >of that object, which can be accessed using the attr or attributes >functions. If you change your code to not use the names function and >instead use attr or attributes to access the names then it should work >for you. > > >You may also want to consider changing your workflow to have your data >objects read into a list rather than global variables, then process >using lapply/sapply (this would require a change in how your data is >saved from your example, but if you can change that then everything >after can be cleaner/simpler/easier/more fool proof/etc.) > > >On Mon, Aug 15, 2016 at 2:49 AM, <G.Maubach at weinwolf.de> wrote: >> Hi All, >> >> I would like to access an object using a sting. >> >> # Create example dataset >> var1 <- c(1, 2, 3) >> var2 <- c(4, 5, 6) >> data1 <- data.frame(var1, var2) >> >> var3 <- c(7, 8, 9) >> var4 <- c(10, 11, 12) >> data2 <- data.frame(var3, var4) >> >> save(file = "c:/temp/test.RData", list = c("data1", "data2")) >> >> # Define function >> t_load_dataset <- function(file_path, >> file_name) { >> file_location <- file.path(file_path, file_name) >> >> print(paste0('Loading ', file_location, " ...")) >> cat("\n") >> >> object_list <- load(file = file_location, >> envir = .GlobalEnv) >> >> print(paste(length(object_list), "dataset(s) loaded from", >> file_location)) >> cat("\n") >> >> print("The following objects were loaded:") >> print(object_list) >> cat("\n") >> >> for (i in object_list) { >> print(paste0("Object '", i, "' in '", file_name, "' contains:")) >> str(i) >> names(i) # does not work >> } >> } >> >> I have only the character vector object_list containing the names of >the >> objects as strings. I would like to access the objects in object_list >to >> be able to print the names of the variables within the object >(usuallly >a >> data frame). >> >> Is it possible to do this? How is it done? >> >> Kind regards >> >> Georg >> >> ______________________________________________ >> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see >> https://stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide >http://www.R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code.