Reputation: 596
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.
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
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
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
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