[R] Dynamic reference, right-hand side of function

Love Bohman
Tue, 05 Dec 2017 00:23:24 -0000

Hi again!
I know you don't find loops evil (well, at least not diabolic :-) ). (After
many hours googling I have realized that thinking about loops rather than lists
is a newbie thing we Stata-users do, I just jokingly pointed it out). Anyway,
I'm really happy that you try to teach me some R-manners. Since I still get
questions about what the h**k I mean by my strange question, I sort it out with
an example:

I had a number of matrices, named in a consecutive manner:

aa_2000 <- as.matrix(read.csv(text="1,0,1,1,0,0,0,0,0,0,1,0,0",
header=FALSE))
aa_2001 <- as.matrix(read.csv( text="0,0,0,1,0,1,1,0,0,0,0,1,0,0",
header=FALSE))
aa_2002 <- as.matrix(read.csv(
text="1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0", header=FALSE))

I needed them to be vectors, and they weren't:

is.vector(aa_2000)

I finally solved it with this loop (well, I admit I shaped up the last line
thanks to William Dunlap):

for (year in 2000:2002){
varname <- paste0("aa_",year)
assign(varname, as.vector(eval(as.name(varname))))
}

The loop obviously solved the problem:

is.vector(aa_2000)

However, you have taught me that I should have solved it more elegant with a
data list:

bb_2000 <- as.matrix(read.csv(text="1,0,1,1,0,0,0,0,0,0,1,0,0",
header=FALSE))
bb_2001 <- as.matrix(read.csv( text="0,0,0,1,0,1,1,0,0,0,0,1,0,0",
header=FALSE))
bb_2002 <- as.matrix(read.csv(
text="1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0", header=FALSE))

is.vector(bb_2000)

datanames <- paste0("bb_", 2000:2002)
datalist <- lapply(datanames, get)
is.vector(datalist[1])


I learned a lot of code today, and I really appreciate it! A million thanks!
My R-superpowers are, well, not as minuscule as when I woke up this morning.

All the best,
Love (or maybe LoveR, my future superhero name)



-----Ursprungligt meddelande-----
Fr?n: Jeff Newmiller [mailto:jdnewmil at dcn.davis.ca.us]
Skickat: den 5 december 2017 00:01
Till: Love Bohman <love.bohman at sociology.su.se>
Kopia: peter dalgaard <pdalgd at gmail.com>; r-help at r-project.org
?mne: Re: [R] Dynamic reference, right-hand side of function

Loops are not evil, and no-one in this thread said they are. But I believe your
failure to provide a reproducible example is creating confusion, since you may
be using words that mean one thing to you and something else to the readers
here.

################################
# A reproducible example includes a tiny set of sample data # Since we cannot
reproducibly refer to filenames (your directories # and files in them are
unlikely to be like mine), I will # use a little trick to read from data in the
example:

dta <- read.csv( text"1.1,3.0,5,7.4,4,2.2,0
", header=FALSE)
str(dta)
#> 'data.frame':    1 obs. of  7 variables:
#>  $ V1: num 1.1
#>  $ V2: num 3
#>  $ V3: int 5
#>  $ V4: num 7.4
#>  $ V5: int 4
#>  $ V6: num 2.2
#>  $ V7: int 0

# note that I did not use "data" as the name because # there is a
commonly-used function by that name in R # that could be confused with your
variable

# if you have your object already in memory, you can use the # dput function to
create R code that will re-create it in our # working environments.

dput( dta )
#> structure(list(V1 = 1.1, V2 = 3, V3 = 5L, V4 = 7.4, V5 = 4L,
#>     V6 = 2.2, V7 = 0L), .Names = c("V1", "V2",
"V3", "V4", "V5",
#> "V6", "V7"), class = "data.frame", row.names
= c(NA, -1L))

# which you can put a variable name in front of in your example code:

dtasample <- structure(list( V1 = 1.1, V2 = 3, V3 = 5L , V4 = 7.4, V5 = 4L,
V6 = 2.2, V7 = 0L ) , .Names = c( "V1"
, "V2", "V3", "V4", "V5",
"V6", "V7" ), class = "data.frame"
, row.names = c(NA, -1L) )

# and starting with that line you can make a self-contained # (reproducible)
example for us to investigate your problem with

# Note that reading a single row of data into R usually gets # a data frame,
which looks like a matrix but is not a matrix.
# Read the Introduction to R about these two types carefully.
# Each column in a data frame can have a different type of data, # but in a
vector or a matrix all rows and columns must be of # the same type.

dtam <- as.matrix( dta )

# If you have any values that R cannot clearly identify as numeric # or integer,
then the next most general type of variable is # character... and that is often
something that trips up newbies, # though I have no evidence that you have any
non-numeric columns # in your data frames.

dtax <- as.vector( dta )
str(dtax)
#> 'data.frame':    1 obs. of  7 variables:
#>  $ V1: num 1.1
#>  $ V2: num 3
#>  $ V3: int 5
#>  $ V4: num 7.4
#>  $ V5: int 4
#>  $ V6: num 2.2
#>  $ V7: int 0

# This actually makes no change to dta, because a data frame is already # a list
of columns, and lists are just vectors that can hold different # types of
variables, so dta is already a kind of vector.

dtan <- as.numeric( dta )
str(dtan)
#>  num [1:7] 1.1 3 5 7.4 4 2.2 0

# I suspect this is what you are trying to accomplish... but really, # if we had
an example of the data you are working with, we would # already know.
################################

Some more explanations of reproducibility [1][2][3]

[1]
http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example

[2] http://adv-r.had.co.nz/Reproducibility.html

[3] https://cran.r-project.org/web/packages/reprex/index.html (read the
vignette)


On Mon, 4 Dec 2017, Love Bohman wrote:

> :-)
> I don't insist on anything, I'm just struggling to learn a new
language and partly a new way of thinking, and I really appreciate the
corrections. I hope I someday will be able to handle lists in R as easy as I
handle loops in Stata...
> Thanks again!
>
> Love
>
>
> -----Ursprungligt meddelande-----
> Fr?n: peter dalgaard [mailto:pdalgd at gmail.com]
> Skickat: den 4 december 2017 23:09
> Till: Love Bohman <love.bohman at sociology.su.se>
> Kopia: r-help at r-project.org
> ?mne: Re: [R] Dynamic reference, right-hand side of function
>
> Um, if you insist on doing it that way, at least use
>
> assign(varname, as.vector(get(varname)))
>
> -pd
>
>> On 4 Dec 2017, at 22:46 , Love Bohman <love.bohman at
sociology.su.se> wrote:
>>
>> Hi!
>> Thanks for the replies!
>> I understand people more accustomed to R doesn't like looping much,
and that thinking about loops is something I do since I worked with Stata a lot.
The syntax from Peter Dalgaard was really clever, and I learned a lot from it,
even though it didn't solve my problem (I guess it wasn't very well
explained). My problem was basically that I have a data matrix consisting of
just 1 row, and I want to convert that row into a vector. However, when trying
to do that dynamically, I couldn't get R to read the right hand side of the
syntax as a variable name instead of a string. However, together with a
colleague I finally solved it with the (eval(as.name()) function (I include the
loop I used below). I understand that looping isn't kosher among you more
devoted R-users, and eventually I hope I will learn to use lists in the future
instead.
>>
>> Thanks!
>> Love
>>
>>
>> for (year in 2000:2007){
>> varname <- paste0("aa_",year)
>> assign(paste0(varname), as.vector(eval(as.name(varname))))
>> }
>>
>> -----Ursprungligt meddelande-----
>> Fr?n: peter dalgaard [mailto:pdalgd at gmail.com]
>> Skickat: den 4 december 2017 16:39
>> Till: Love Bohman <love.bohman at sociology.su.se>
>> Kopia: r-help at r-project.org
>> ?mne: Re: [R] Dynamic reference, right-hand side of function
>>
>> The generic rule is that R is not a macro language, so looping of names
of things gets awkward. It is usually easier to use compound objects like lists
and iterate over them. E.g.
>>
>> datanames <- paste0("aa_", 2000:2007)
>> datalist <- lapply(datanames, get)
>> names(datalist) <- datanames
>> col1 <- lapply(datalist, "[[", 1)
>> colnum <- lapply(col1, as.numeric)
>>
>> (The 2nd line assumes that the damage has already been done so that
>> you have aa_2000 ... aa_2007 in your workspace. You might
>> alternatively create the list directly while importing the data.)
>>
>> -pd
>>
>>> On 4 Dec 2017, at 12:33 , Love Bohman <love.bohman at
sociology.su.se> wrote:
>>>
>>> Hi R-users!
>>> Being new to R, and a fairly advanced Stata-user, I guess part of
my problem is that my mindset (and probably my language as well) is wrong.
Anyway, I have what I guess is a rather simple problem, that I now without
success spent days trying to solve.
>>>
>>> I have a bunch of datasets imported from Stata that is labelled
aa_2000 aa_2001 aa_2002, etc. Each dataset is imported as a matrix, and consists
of one column only. The columns consists of integer numbers. I need to convert
the data to vectors, which I found several ways to do. I use, for example:
>>> aa_2000 <- as.numeric(aa_2000[,1])
>>> However, when trying to automate the task, so I don't have to
write a line of code for each dataset, I get stuck. Since I'm a Stata user,
my first attempt is trying to make a loop in order to loop over all datasets.
However, I manage to write a loop that works for the left-hand side of the
syntax, but not for the right-hand side.
>>> I have included some examples from my struggles to solve the issue
below, what they all have in common is that I don't manage to call for any
"macro" (is that only a Stata-word?) in the right hand side of the
functions. When I try to replace the static reference with a dynamic one (like
in the left-hand side), the syntax just doesn't work.
>>>
>>> I would very much appreciate some help with this issue!
>>> All the best,
>>> Love
>>>
>>> year <- 2002
>>> dataname <- paste0("aa_",year)
>>> assign(paste0(dataname), as.numeric(aa_2002[,1]))
>>>
>>> year <- 2003
>>> assign(paste0("aa_",year), as.numeric(aa_2003))
>>>
>>> year <- 2005
>>> assign(paste0("aa_",year), aa_2005[,1])
>>>
>>> list1 <- c(2000:2007)
>>> list1[c(7)]
>>> assign(paste0("aa_",list1[c(7)]),
as.numeric(paste0(aa_2006)))
>>>
>>>
>>> 	[[alternative HTML version deleted]]
>>>
>>> ______________________________________________
>>> 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.
>>
>> --
>> Peter Dalgaard, Professor,
>> Center for Statistics, Copenhagen Business School Solbjerg Plads 3,
>> 2000 Frederiksberg, Denmark
>> Phone: (+45)38153501
>> Office: A 4.23
>> Email: pd.mes at cbs.dk  Priv: PDalgd at gmail.com
>>
>>
>>
>>
>>
>>
>>
>>
>>
>
> --
> Peter Dalgaard, Professor,
> Center for Statistics, Copenhagen Business School Solbjerg Plads 3, 2000
Frederiksberg, Denmark
> Phone: (+45)38153501
> Office: A 4.23
> Email: pd.mes at cbs.dk  Priv: PDalgd 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.

---------------------------------------------------------------------------
Jeff Newmiller                        The     .....       .....  Go Live...
DCN:<jdnewmil at dcn.davis.ca.us>        Basics: ##.#.       ##.#.  Live
Go...
                                       Live:   OO#.. Dead: OO#..  Playing
Research Engineer (Solar/Batteries            O.O#.       #.O#.  with
/Software/Embedded Controllers)               .OO#.       .OO#.  rocks...1k