0

I'm trying to loop over variables (I'm still struggling to get my head around the apply() family, one day soon) and construct the variable names that I wish to obtain the labels for.

A simplified example is perhaps easiest...

library(Hmisc)
t <- data.frame(matrix(1:100, 10))
label(t$X1)  <- "This is my first variable"
label(t$X2)  <- "This is my second variable"
label(t$X3)  <- "This is my third variable"
label(t$X4)  <- "This is my fourth variable"
label(t$X5)  <- "This is my fifth variable"
label(t$X6)  <- "This is my sixth variable"
label(t$X7)  <- "This is my seventh variable"
label(t$X8)  <- "This is my eighth variable"
label(t$X9)  <- "This is my ninth variable"
label(t$X10) <- "This is my tenth variable"
for(x in 1:10){
  my.label <- label(paste("t$X", x, sep=""))
  print(my.label)
}

When run this gives....

[1] ""
[1] ""
[1] ""
[1] ""
[1] ""
[1] ""
[1] ""
[1] ""
[1] ""
[1] ""

When I'm expecting to see

[1] "This is my first variable"
[1] "This is my second variable"
[1] "This is my third variable"
[1] "This is my fourth variable"
[1] "This is my fifth variable"
[1] "This is my sixth variable"
[1] "This is my seventh variable"
[1] "This is my eighth variable"
[1] "This is my ninth variable"
[1] "This is my tenth variable"

I know the paste() function is working correctly because...

for(x in 1:10){
  print(paste("t$X", x, sep=""))
}
[1] "X$1"
[1] "X$2"
[1] "X$3"
[1] "X$4"
[1] "X$5"
[1] "X$6"
[1] "X$7"
[1] "X$8"
[1] "X$9"
[1] "X$10"

I'm stumped, I've tried placing the paste() within eval() as in...

for(x in 1:10){
  my.label <- label(eval(paste("t$X", x, sep="")))
  print(my.label)
}

...but no joy. It seems such a simple thing, and I've tried searching for solutions but clearly aren't describing it properly with phrases I'm trying hence asking here.

Insights and pointers very much appreciated.

Thanks,

slackline

EDIT : The above is a simplified example to illustrate what I am trying to achieve which is a bit more complex, currently my code looks like...

for(type1 in c("bouldering", "routes")){
  if(type1 == "bouldering"){
    part   <- c("indoors", "outdoors")
    xlabel <- "Grade (Fontainebleau)"
  }
  else if(type1 == "routes"){
    part <- c("onsight", "redpoint")
    xlabel <- "Grade (French Sports)"
  }
  for(type2 in part){
    for(training in c("pullup.rep", "pullup.weight", "hang.time", "hang.size", "bench.press", "bench.press.scaled", "dead.lift", "dead.lift.scaled", "front.lever", "height", "weight", "bmi")){
      ### Obtain the current variables label for using in the graph
      ylabel <- label(paste("clean.data", training, sep="$"))
      ### Paste the bouldering/routes together with indoors/
      ### outdoors or onsight/redpoint so variables and files can be constructed
      file.stub <- paste(type1, type2, sep="-")
      metric    <- paste(type1, type2, sep=".")
      file.out  <- paste("latex/figures/", gsub("\\.", "-", training) , "-", file.stub, ".png", sep="")
      png(file.out, width=1024, height=768)
      t <- qplot(metric, training,
                 data     = clean.data,
                 geom     = "boxplot",
                 fill     = factor(metric),
                 xlab     = xlabel,
                 ylab     = ylabel)
      t + opts(legend.position = "none")
      dev.off()
    }
  }
}

So currently I don't get a label, and I don't get graphs because the commands (label() and qplot()) don't know that I'm referring to column names with the data frame clean.data

5
  • 2
    Read what you've written carefully. label(paste("t$X", x, sep="")) says "get the label from the character string I'm making with paste". Of course this doesn't have a label. Additionally, label is vectorized, so label(t) is enough to get the labels of the columns in t. This is much better than looping over the column indexes. Commented Oct 26, 2012 at 15:04
  • @mplourde Ok, I understand now why it doesn't work. This is of course a simplified example (as is often useful when asking questions), in reality I wish to construct variable names, obtain their labels, use those labels when graphing the variable, so whilst using label(t) would work for this overly simplified example it won't be applicable to my ultimate aim (I've edited the original post to include the code I am trying to work with so its a bit clearer, although obviously the loop doesn't achieve what I want it to yet). Commented Oct 26, 2012 at 15:11
  • @mplourde : I sort of knew I wasn't on the right track which was why I'd tried using eval() around the paste. I've also tried get() (I'm pretty sure assign()) won't work in this case in the construct I'm using here, although there might be another way to write the code that does work with assign() perhaps?). Commented Oct 26, 2012 at 15:20
  • 1
    instead of using $, try using the [[ to access the columns of t, e.g., my.label <- label(t[[paste("X", x, sep="")]]). If the name of t also needs to be a variable, you could replace t in the latter with get(y), where y is the name of the data.frame. Commented Oct 26, 2012 at 15:23
  • @mplourde : Excellent that solves the first part of my overall problem of getting the labels, thank you. Commented Oct 26, 2012 at 15:27

2 Answers 2

2

This will work:

for(x in 1:10){
  my.label <- label(t[paste("X", x, sep="")])
  print(my.label)
}

This would be simpler:

label(t)
Sign up to request clarification or add additional context in comments.

3 Comments

@nograpes : see the full example as to why a vector of labels isn't ultimately what I'm after. Your first solution is exactly what mplourde suggested and that worked. Thanks both.
@mplourde: Sorry, I didn't mean to steal your answer. I didn't read the comments well.
As a general rule of thumb is using my.data.frame[[X1]] to refer to column names a better approach than my.data.frame$X1? Am I likely to have easier code to read and less problems? Seems it is in this instance but would I encounter problems in other situations?
1

Hey this is kind of a 'hack', but try this:

for (i in 1:10)    {
my.label <- label(t[,names(t)==paste("X", i, sep="")])
print(my.label)
}

So instead of turning the pasted material into a data frame column call, you turn the column name into a character string. It worked for me when I tried it.

2 Comments

Ok so thats using the vectorisation of the labels but selecting out the one that matches the current loop. Good to have alternatives. I'm thinking indexing column names using square brackets is probably the best approach in future.
Yeah @nogrape's answer is much simpler now that I see it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.