Reputation: 635
I see there is another related question, but the answer isnt what I am looking for. I want a function that can be assigned to an object, but still will print the output even when assigned, but not double print it.
In this case:
fun <- function(x) {
print(x+1)
x+1
}
a <- fun(3)
In this case, it would both save to a, and it would print to console, which is what I want.
But in this case:
fun(3)
It would print to the console twice. Is there a way to get the desired result from case 1, without double printing on case 2?
Upvotes: 4
Views: 696
Reputation: 145785
R functions shouldn't have unasked for "side effects". This isn't a rule, but a strong recommendation. As evidence for it being good practice, there are plenty of questions on SO like this one where a poorly behaved function prints output using print
or cat
that the end user struggles to disable.
Based on this, I would strongly encourage you to either use message()
rather than print()
or to add an argument that can disable the printing. message()
is the "right" way print to the console during execution, but it won't format the result nicely depending on the data structure.
Thus, if your function expects simple outputs then I would recommend doing it like this:
fun <- function(x) {
result = x + 1
message(result)
invisible(result)
}
If it might have more complicated output, you could try something like this (demoing on mtcars
):
fun <- function(x) {
result = head(mtcars)
sapply(capture.output(print(result)), message)
invisible(result)
}
Messages can easily be suppressed by wrapping the call in suppressMessages()
, and message = F
is a handy argument for knitr
code chunks to say "ignore the messages".
The other option is to add an argument
fun <- function(x, quietly = FALSE) {
result = x + 1
if (!quietly) print(result)
invisible(result)
}
And I'd also think long and hard about whether this strange behavior is really necessary. Usually, having functions that behave as expected is better than having special cases that throw expectations.
Upvotes: 1
Reputation: 17279
You can accomplish this same behavior with any function in R that visibly returns an object by wrapping it in parentheses.
fun <- function(x) {
x+1
}
> (fun(3))
[1] 4
> (a = fun(3))
[1] 4
> a
[1] 4
Or, equivalently, you may simply call print
on your assignment.
> print(fun(3))
[1] 4
I'm not sure rolling this functionality into a function has any benefits over using the existing print
method outside of a function.
Upvotes: 1
Reputation: 1256
Assuming that you still want your function to return the 'x+1' value, you could just wrap it in the invisible function:
fun <- function(x) {
print(x+1)
invisible(x+1)
}
> fun(3)
[1] 4
> a = fun(3)
[1] 4
> a
[1] 4
This will only print it out once, while still retaining the 'x+1' value.
Upvotes: 5