This is probably a duplicate, but I don't seem to find this specific case.
Say I have two lists:
list1 <- as.list(c(5, 8, 9))
list2 <- as.list(c(8, 10, 11))
I know how to apply a function to one list. Say I want to apply the following to list1
:
lapply(list1, function(x){x+100})
But what if I only want to apply such function to list1
when the corresponding value in list2
is >=10
? So that my result is:
[[1]]
[1] 5
[[2]]
[1] 108
[[3]]
[1] 109
And even more, how can I sum 100 to the value in list1
and subtract the value in list2
only when the value in list2
is >=10
?
Something like the following, which obviously does not work:
lapply(list1, list2, function(x,y){if (y>=10) x+100-y})
Thanks!
I think you're looking for Map()
, which is mapply()
without simplification:
mapply
is a multivariate version ofsapply
.mapply
appliesFUN
to the first elements of each...
argument, the second elements, the third elements, and so on.
For reasons that I imagine are only known to the R devs, unlike lapply()
, sapply()
and tapply()
, the function is the first argument of mapply()
and Map()
.
Map(
\(x1, x2) if (x2 >= 10) x1 + 100 else x1,
list1,
list2
)
# [[1]]
# [1] 5
# [[2]]
# [1] 108
# [[3]]
# [1] 109
If you want to be fancy you could remove the if()
statement and define the function as \(x1, x2) x1 + 100 * (x2 >= 10)
but personally I think the lack of explicitness makes it less comprehensible.
Of course you could also do this with ifelse(list2 >= 10, unlist(list1) + 100, list1)
in this case but Map()
is more general.
Your second example could be expressed as Map(\(x, y) if (y >= 10) x + 100 - y else x, list1, list2)
.