15

I have a function that looks like this:

removeRows <- function(dataframe, rows.remove){
  dataframe <- dataframe[-rows.remove,]
  print(paste("The", paste0(rows.remove, "th"), "row was removed from", "xxxxxxx"))
}

I can use the function like this to remove the 5th row from the dataframe:

removeRows(mtcars, 5)

The function output this message:

"The 5th row was removed from xxxxxxx"

How can I replace xxxxxxx with the name of the dataframe I have used, so in this case mtcars?

3
  • Are you aware that dataframe <- dataframe[rows.remove,] does not propagate changes outside the function call? Also, rows.remove is supposed to be negative. Commented May 25, 2013 at 1:43
  • Post edited to -rows.remove. Sorry, don't understand what you mean by 'does not propagate changes outside the function call'. This is my fault, not yours. Could you expand please? Commented May 25, 2013 at 5:45
  • 1
    if you call removeRows as it stands now, R will create a copy of your dataframe and modify the copy. When the function terminates, the (modified) copy is destroyed, and the original dataframe will be untouched. If you want to change the original data, you must call it as mtcars <- removeRows(mtcars, 5) AND add the line dataframe (or return(dataframe)) at the end of the function code. Commented May 27, 2013 at 12:14

2 Answers 2

16

You need to access the variable name in an unevaluated context. We can use substitute for this:

removeRows <- function(dataframe, rows.remove) {
  df.name <- deparse(substitute(dataframe))
  dataframe <- dataframe[rows.remove,]
  print(paste("The", paste0(rows.remove, "th"), "row was removed from", df.name))
}

In fact, that is its main use; as per the documentation,

The typical use of substitute is to create informative labels for data sets and plots.

Sign up to request clarification or add additional context in comments.

3 Comments

Are you aware of a similar idiom in Python? (OT, but I'm just wondering...)
@krlmlr Python has nothing like this – substitute is essentially a hack. You can however inspect the call stack in Python – it might be able to retrieve the parameter name through that but it’s going to be more complex since you’ll have to retrieve and inspect the calling context’s byte code.
Thanks. It's just that I'd be so glad to be able to write just loginfo(expression) instead of loginfo("expression: %s" % expression)... -- Just found it: In Python, there is another option to achieve this: github.com/lihaoyi/macropy#tracing
0

I would like to point out that df.name <- deparse(substitute(dataframe)) should be used at the top of your function before any transformation is done. I used it right at the end of my function, just before doing ggsave, which does not return the name but somehow what is inside the dataframe, which is not what you want. This gave me a lot of headache.

So something like this :

function(df){
df.name <- deparse(substitute(dataframe))
ggplot()
ggsave()
}

Comments

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.