0

I want to create a function that transforms its object.

I have tried to transform the variable as you would normally, but within the function.

This works:

vec <- c(1, 2, 3, 3)
vec <- (-1*vec)+1+max(vec, na.rm = T)
[1] 3 2 1 1

This doesn't work:

vec <- c(1, 2, 3, 3)

func <- function(x){
  x <- (-1*x)+1+max(x, na.rm = T))
}

func(vec)
vec
[1] 1 2 3 3
Marco Pastor Mayo
  • 803
  • 11
  • 25
  • Not clear to me what you mean by transform. Are you just trying to reverse the order of items in a vector? – Bill O'Brien Sep 18 '19 at 13:06
  • Yes, although I would like to know how to apply functions to objects directly. Basically, instead of doing `x <- 2*x' I would like to have something like `func(x)` – Marco Pastor Mayo Sep 18 '19 at 13:06
  • 3
    Just assign the values back to `vec`, `vec <- func(vec)` after adding `return(x)` in the function. – Ronak Shah Sep 18 '19 at 13:07
  • 2
    Your "func" function is not returning any value. Delete the "x <- " in the function body. – Bill O'Brien Sep 18 '19 at 13:07
  • 1
    Your vector is passed to the function by value, not by reference – slava-kohut Sep 18 '19 at 13:09
  • I would like to avoid doing ```vec <- func(vec)``` because I will be applying this function to subsets of a dataframe, and don't want to have to do the arrow assignment – Marco Pastor Mayo Sep 18 '19 at 13:10
  • 2
    Possible duplicate of [R: Passing a data frame by reference](https://stackoverflow.com/questions/11207497/r-passing-a-data-frame-by-reference) – John Coleman Sep 18 '19 at 13:14
  • 3
    @MarcoPastorMayo That's a bad idea. Functions with side effects make nothing easier or more convenient. – Roland Sep 18 '19 at 13:16
  • Thank you for the useful comments. Having looked at the apply, lapply, and sapply functions, it seems that @Roland is right: I'll have to do the arrow assignment. – Marco Pastor Mayo Sep 18 '19 at 13:20

1 Answers1

3

R is functional so normally one returns the output. If you want to change the value of the input variable to take on the output value then it is normally done by the caller, not within the function. Using func from the question it would normally be done like this:

vec <- func(vec)

Furthermore, while you can overwrite variables it is, in general, not a good idea. It makes debugging difficult. Is the current value of vec the input or output and if it is the output what is the value of the input? We don't know since we have overwritten it.

func_ovewrite

That said if you really want to do this despite the comments above then:

# works but not recommended
func_overwrite <- function(x) eval.parent(substitute({
  x <- (-1*x)+1+max(x, na.rm = TRUE)
}))


# test
v <- c(1, 2, 3, 3)
func_overwrite(v)
v
## [1] 3 2 1 1

Replacement functions

Despite R's functional nature it actually does provide one facility for overwriting although the function in the question is not really a good candidate for it so let us change the example to provide a function incr which increments the input variable by a given value. That is, it does this:

x <- x + b

We can write this in R as:

`incr<-` <- function(x, value) x + value

 # test
 xx <- 3
 incr(xx) <- 10
 xx
 ## [1] 13

T vs. TRUE

One other comment. Do not use T for true. Always write it out. TRUE is a reserved name in R but T is a valid variable name so it can lead to hard to find errors such as when someone uses T for temperature.

G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341