Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subtract value from each list's element in R

Tags:

r

I need to subtract specified value from each list element in R. In this article is mentioned that for such tasks the apply family of functions are used instead of loops. I've tried following:

# Define list
> a = 1:20

# Substraact this from each element
> substract_me = 5

# Function for substracting
> substract = function(x,y) { ret = x-y; return(ret) }

# The problem is that I do not know how to access the current array element and pass it to substract function
lapply(a, substract)

Here is mentioned that the anonymous functions can be also used, but it did not worked for me and I get syntax error. Indeed it looks to me just like syntactic sugar. The problem remain the same, that I need some placeholder or something when I am using lapply function so I can access the current list element:

lapply(a, function([WHAT TO ADD HERE???],substract_me) substract([WHAT TO ADD HERE???],substract_me))

Here is something probably related but I did not figure out how stuff works from posted code snippets.

like image 335
Wakan Tanka Avatar asked Nov 30 '22 17:11

Wakan Tanka


2 Answers

The title of the original question asks for how to apply subtract to a list type r object, but the example given subtracts from a vector a = 1:20.

The approved answer by MrFlick is exactly correct for vectors, but does not work with a list. For example, subtracting from the following list of integer vectors fails.

a <- list(v1 = 1:10, v2 = -5:5, v3 = 1:5)
# $v1
# [1]  1  2  3  4  5  6  7  8  9 10
# $v2
# [1] -5 -4 -3 -2 -1  0  1  2  3  4  5
# $v3
# [1] 1 2 3 4 5
subtract_me <- 5
a - subtract_me # produces a non-numeric argument to binary operator error

lapply with an inline-defined anonymous function is an easy way to accomplish the desired subtraction on a list.

subtract_me <- 5
lapply(a, function(x, subt_amnt) x - subt_amnt, subt_amnt = subtract_me)
# $v1
# [1] -4 -3 -2 -1  0  1  2  3  4  5
# $v2
# [1] -10  -9  -8  -7  -6  -5  -4  -3  -2  -1   0
# $v3
# [1] -4 -3 -2 -1  0

the subtraction function can be defined outside of lapply. Error handling and other checks in the function would likely warrant a standalone function.

For more info on the uses of anonymous functions see http://adv-r.had.co.nz/Functional-programming.html#anonymous-functions

As Requested by MoonS, an alternative approach would be to write the function explicitly outside the lapply call.

subtract_first_element_only <- function(x, subt_amnt) {
  # insert any additional logic to determine the subtract amount or 
  # from which elements to subtract here
  vector_out <- c(x[1] - subt_amnt,x[2:length(x)])
  return(vector_out)
}

lapply(a, subtract_first_element_only, subt_amnt = subtract_me)

#
like image 34
icj Avatar answered Dec 05 '22 13:12

icj


Subtraction in R is vectorized

a = 1:20
substract_me = 5
a - substract_me
# [1] -4 -3 -2 -1  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15

No need for apply functions here.

like image 170
MrFlick Avatar answered Dec 05 '22 12:12

MrFlick