lawyeR
lawyeR

Reputation: 7664

In R, use the ls() function with a regular expression to save only character objects?

I have created more than 100 objects that are each two-part character strings. They all begin the first part with an equal sign, For example,

intro <- c("=intro", "For calendar year 2007 blah blah.")

 str(intro)
 chr [1:2] "=intro" ...

My goal is to combine all of those objects into a data frame that has the first part, the one preceded by "=" in the first column and the second part, the sentence or sentences, in the second column.

To save all the objects as a data frame:

character.objects <- data.frame(chrobjects = ls(), stringsAsFactors = FALSE) 

Is there a way to use the pattern = argument of the ls function so that only the chr [1:2] objects are saved in the character.objects data frame? Or, how else can I achieve my goal?

Upvotes: 0

Views: 1113

Answers (2)

akrun
akrun

Reputation: 887691

You could also try.

Creating some data

intro <- c("=intro", "For calendar year 2007 blah blah.")
intro1 <- c("intro", "For calendar year 2008 blah blah.")
intro2 <- c("intro=", "For calendar year 2009 blah blah.")
intro3 <- c("=intro", "For calendar year 2010 blah")

library(stringr)
res <- do.call(rbind, lapply(mget(ls())[sapply(mget(ls()), is.character)], function(x) {
x1 <- x[str_detect(x, perl("(?<=^=)[[:alnum:]]+"))[1]]
if (length(x1) > 0) 
    data.frame(key = x1[1], val = x1[2], stringsAsFactors = F)
}))

res
#         key                               val
#intro  =intro For calendar year 2007 blah blah.
#intro3 =intro       For calendar year 2010 blah

Upvotes: 0

MrFlick
MrFlick

Reputation: 206486

First of all, creating a bunch of variables like that is probably not a good design strategy. Most likely those values should be combined into a list or something. But one way to find the names of all such variables is

whatIwant<-function(x) {
    z <- get(x)
    if (is.character(z)) {
        if (length(z)==2) {
            if (substr(z[1],1,1)=="=")
                return(TRUE)
        }
    }
    return(FALSE)
}

myvars <- Filter(whatIwant, ls())

So ls() returns a character vector with the names of all the objects in your workspace. I use Filter to reduce that list to only the names we are interested in. I wrote the custom function whatIwant to help find those values.

The helper function uses the names from ls() and then actually gets the object via get(). Then we check the class and length and values to make sure it matches your criteria. So myvars should be a character vector with only the names of the variables that match your description

And then we can turn that vector of variable names into a data.frame containing their values with something like

do.call(rbind, lapply(mget(myvars), function(x) data.frame(key=x[1], val=x[2])))

or maybe

myvals <- mget(myvars)
data.frame(key=sapply(myvals, `[`, 1), val=sapply(myvals, `[`, 2))

Note this solution does not use the pattern= parameter of the ls() function because that parameter only works against the name of the objects, not the contents or type of the objects themselves.

Upvotes: 1

Related Questions