Nikita Belooussov
Nikita Belooussov

Reputation: 596

increment multiple arguments in lapply

Is there a way to increment two arguments in an lapply function? For example

test <- function(pos,value){
   list[pos,value]
}

data=c(1,4,32,54) #not global
lapply(X=1:length(data),test, value=data[X])#this is the idea but the code doesnt work

The output would be list(list(1,1),list(2,4),list(3,32),list(4,54))

Another example would be

test <- function(pos,value,value2){
   list(pos,value,value2)
}

data=c(1,4,32,54) #not global
data2=c(2,6,3,21) #not global
lapply(X=1:length(data),test, value=data[X], value2=data2[X]) #this is the idea but the code doesn't work

The output would be list(list(1,1,2),list(2,4,2),list(3,32,6),list(4,54,21))

This may also help. I am pretty much trying to change the for loop into an lapply.

test <- function(pos,value,value2){
   list(pos,value,value2)
}

data=c(1,4,32,54) #not global
data2=c(2,6,3,21) #not global
for(i:length(data)){
  result=list(result,test(i,data[i],data2[i]))
}

Since the variables arent global I can't have the test function as

test <- function(pos){
   list(pos,data[pos],data2[pos])
}

I know that there is an easier way of writing this code to accomplish the same thing. But I am looking for a way to specifically increment two variables, or use the incremented value in an argument. The variables used in the examples, arent global, so I can't use them in the function and it needs to use the lapply function. In the codes, the lapply lines do not work, it was just the demonstrate the concept of what I am trying to do. Thank you.

Edit

So after learning about the mapply function. I realized that what I want is to create an lapply function that acts like an mapply

Upvotes: 3

Views: 729

Answers (3)

hello_friend
hello_friend

Reputation: 5788

Using the "<-" assignment operator:

num_vec <- c(1, 4, 32, 54)

num_vec2 <- c(2, 6, 3, 21)

# Using lapply: 

lapply(seq_along(num_vec), function(x){return(c(x, num_vec[x], num_vec2[x]))})

Using the " = " assignment operator:

num_vec = c(1, 4, 32, 54)

num_vec2 = c(2, 6, 3, 21)

# Using lapply: 

lapply(seq_along(num_vec), function(x){return(c(x, num_vec[x], num_vec2[x]))})

In the above case the assignment operator doesnt make a difference and doesnt relate to local or global assignment.

In response to the additional query about wanting to retrieve elements based on a value in either vector:

num_vec = c(1, 4, 32, 54)


num_vec2 = c(2, 6, 3, 21)

test <- function(num_vec, num_vec2, val) {
  if (!hasArg(val)) {
    val <- 1:max(c(num_vec, num_vec2))
  } else{
    as.numeric(c(val))
  }

  lapply(seq_along(num_vec),

         function(x) {
           return(c(x, num_vec[x], num_vec2[x]))
         })[ifelse(
           val %in% num_vec &

             !(val %in% num_vec2),

           which(num_vec %in% val),

           ifelse(
             !(val %in% num_vec2) &

               !(val %in% num_vec2),

             0,

             ifelse(
               val %in% num_vec &

                 val %in% num_vec2,

               c(which.min(
                 which(val %in% num_vec), which(val %in% num_vec2)
               ),

               which.max(
                 which(val %in% num_vec), which(val %in% num_vec2)
               )),

               which(val %in% num_vec2)
             )
           )
         )]

}

test(num_vec, num_vec2, 54)

Upvotes: 1

ThomasIsCoding
ThomasIsCoding

Reputation: 101343

I guess mapply is a better choice than lapply in you case.

Assuming you have a variable number of input arguments, you can rewrite test as

test <- function(pos,...){
  list(pos, ...)
}

For input in your example

data=c(1,4,32,54) #not global
data2=c(2,6,3,21) #not global

using mapply can get you there:

mapply(test, seq_along(data), data, data2, SIMPLIFY = F)

Upvotes: 1

Kumar Manglam
Kumar Manglam

Reputation: 2832

Just adding to the answer by @hello_friend, you can pass arguments to the function, using lapply. From the question, I understand that you want to pass more than one argument to function. The below code tries to do that. Please have a look.

vec1 <- c(1, 3, 5, 7)

vec2 <- c(2, 4, 6, 8)

test <- function(pos, vec_arg1, vec_arg2){
  return(c(pos, vec_arg1[pos], vec_arg2[pos]))
}
# Using lapply: 

lapply(seq_along(num_vec), test, vec1, vec2)

Upvotes: 0

Related Questions