Applying a function to two lists?
You seem to be looking for mapply
. Here's an example:
listA <- list(matrix(rnorm(2000), nrow=10),
matrix(rnorm(2000), nrow=10))
listB <- list(matrix(rnorm(2000), nrow=10),
matrix(rnorm(2000), nrow=10))
mapply(function(X,Y) {
sapply(1:10, function(row) cor(X[row,], Y[row,]))
}, X=listA, Y=listB)
How applying a function to multiple lists and get a list as the output in R?
As RonakShah said in the comment, Map
is likely the answer here.
Think of it this way: lapply
applies a function to each element of one list:
myfunc <- function(x) {
# do something with x
}
lapply(1:4, myfunc)
## unrolls to be the equivalent of ...
list(
myfunc(1),
myfunc(2),
myfunc(3),
myfunc(4)
)
Map
, however, "zips" each n
th element of multiple lists together. The equivalent of the above lapply
using Map
is
Map(myfunc, 1:4)
but there is a lot more.
myfunc_many <- function(x, y, z) {
# do something with all three args
}
Map(myfunc_many, 1:4, 11:14, 21:24)
## unrolls to
list(
myfunc_many(1, 11, 21),
myfunc_many(2, 12, 22),
myfunc_many(3, 13, 23),
myfunc_many(4, 14, 24)
)
Map
can deal with an arbitrary number of lists; if your function is variadic (accepts arbitrary number of arguments), it will still work (though your function has to have built-in mechanisms for dealing with that, making it variadic):
myfunc_variadic <- function(...) {
dots <- list(...)
# do something with dots
}
Map(myfunc_variadic, 1:4)
Map(myfunc_variadic, 1:4, 11:14)
Map(myfunc_variadic, 1:4, 11:14, 21:24, 31:34, 41:44)
In all of the examples above, I've used vectors as each argument, but it works just as well with lists of things. As a final example,
set.seed(42)
L1 <- replicate(2, matrix(sample(6), nrow = 2), simplify = FALSE)
L2 <- replicate(2, matrix(sample(6), nrow = 2), simplify = FALSE)
L1
# [[1]]
# [,1] [,2] [,3]
# [1,] 1 6 2
# [2,] 5 4 3
# [[2]]
# [,1] [,2] [,3]
# [1,] 2 1 5
# [2,] 6 3 4
L2
# [[1]]
# [,1] [,2] [,3]
# [1,] 4 5 3
# [2,] 1 2 6
# [[2]]
# [,1] [,2] [,3]
# [1,] 2 1 5
# [2,] 3 4 6
Map(`*`, L1, L2)
# [[1]]
# [,1] [,2] [,3]
# [1,] 4 30 6
# [2,] 5 8 18
# [[2]]
# [,1] [,2] [,3]
# [1,] 4 1 25
# [2,] 18 12 24
How to apply a function on two lists of data frames?
We can use Map
to apply the function on corresponding elements of 'list_A' and 'list_B'
Map(`*`, list_A, list_B)
As @RHertel mentioned in the comments, if the function needed is %*%
Map(function(x,y) as.matrix(x) %*% as.matrix(y), list_A, list_B)
How to apply the same function to multiple lists
I'm not sure whether I understood your question correctly. As fgblomqvist commented, I replaced 1 if 'a' in a
by 1 if x == 'a'
in the list comprehension. Then I basically reproduced your second step with a for-loop and after that I used zip
to iterate over the list values of all lists synchronously in order to calculate the sum.
a = ['a','b','c','d','e']
b = ['b','a','c','e','a']
c = ['a','b','c','d','e']
# add the lists to a list.
lists = [a,b,c]
outcomes = []
for l in lists:
outcome = [1 if x == 'a' else 99 for x in l]
outcomes.append(outcome)
print(f'one of the outcomes: {outcome}')
results = []
# iterate over all list values synchronously and calculate the sum
for outs in zip(*outcomes):
results.append(sum(outs))
print(f'sum of {outs} is {sum(outs)}')
print(f'final result:{results}')
This is the output:
one of the outcomes: [1, 99, 99, 99, 99]
one of the outcomes: [99, 1, 99, 99, 1]
one of the outcomes: [1, 99, 99, 99, 99]
sum of (1, 99, 1) is 101
sum of (99, 1, 99) is 199
sum of (99, 99, 99) is 297
sum of (99, 99, 99) is 297
sum of (99, 1, 99) is 199
final result:[101, 199, 297, 297, 199]
edit: To avoid looping twice you could join the loops together like so:
lists = [a,b,c]
sums = []
for values in zip(*lists):
the_sum = 0
for val in values:
the_sum += 1 if val == 'a' else 99
sums.append(the_sum)
print(f'sums: {sums}')
Keep in mind you can replace the 1 if val == 'a' else 99
by some_func(val)
Lapplying a function over two lists of dataframes in R
Here, we could use Map
from base R
to apply the function on the corresponding elements of both the list
s
out <- Map(my_function, list_A, list_B)
lapply
can also be used, if we loop over the sequence of one of the list
out <- lapply(seq_along(list_A), function(i)
my_function(list_A[[i]], list_B[[i]]))
which is similar to using a for
loop
out <- vector('list', length(list_A))
for(i in seq_along(list_A)) out[[i]] <- my_function(list_A[[i]], list_B[[i]])
Apply a function to each combination of two lists elements
Or another option with pmap
and crossing
library(tidyr)
library(purrr)
library(dplyr)
crossing(v1 = 0:1, v2 = 1:2) %>%
pmap_dbl(~ qnorm(p = 0.05, mean = ..1, sd = ..2, lower.tail = FALSE))
[1] 1.644854 3.289707 2.644854 4.289707
If we need a data.frame/tibble, use the pmap
code within the mutate
to return as a new column
crossing(v1 = 0:1, v2 = 1:2) %>%
mutate(new = pmap_dbl(., ~ qnorm(p = 0.05,
mean = ..1, sd = ..2, lower.tail = FALSE)))
# A tibble: 4 × 3
v1 v2 new
<int> <int> <dbl>
1 0 1 1.64
2 0 2 3.29
3 1 1 2.64
4 1 2 4.29
NOTE: If we don't need the other columns, use transmute
instead of mutate
or specify .keep = "used"
in mutate
crossing(v1 = 0:1, v2 = 1:2) %>%
mutate(new = pmap_dbl(., ~ qnorm(p = 0.05,
mean = ..1, sd = ..2, lower.tail = FALSE)), .keep = "used")
# A tibble: 4 × 1
new
<dbl>
1 1.64
2 3.29
3 2.64
4 4.29
Run a function for each element in two lists in Pandas Dataframe Columns
This works:
# Generate DataFrame
df = pd.DataFrame (data, columns = ['col1','col2'])
# Clean Data (strip out trailing commas on some words)
df['col1'] = df['col1'].map(lambda lst: [x.rstrip(',') for x in lst])
# 1. List comprehension Technique
# zip provides pairs of col1, col2 rows
result = [[get_top_matches(u, [v]) for u in x for w in y for v in w] for x, y in zip(df['col1'], df['col2'])]
# 2. DataFrame Apply Technique
def func(x, y):
return [get_top_matches(u, [v]) for u in x for w in y for v in w]
df['func_scores'] = df.apply(lambda row: func(row['col1'], row['col2']), axis = 1)
# Verify two methods are equal
print(df['func_scores'].equals(pd.Series(result))) # True
print(df['func_scores'].to_string(index=False))
Thanks all who helped
applying a function to multiple lists (R)
For the example shared, where all the elements of source
have the same order you can do :
cols <- paste0('source.val_', sort(unique(unlist(source))))
setNames(do.call(rbind.data.frame, source.val), cols)
# source.val_5 source.val_10 source.val_20 source.val_30
#1 A B C D
#2 B B D D
#3 C B A D
#4 D B B D
However, for a general case where every value in source
do not follow the same order you can reorder source.val
based on source
:
source.val <- Map(function(x, y) y[order(x)], source, source.val)
and then use the above code.
How to apply a function to two elements of a list - Haskell
yes on way is to define a recursive function - what you need to think about (and what we don't know) is what should happen if the input list has uneven item-count?
And of course how do you want to collect the results of that function?
Assuming you just ignore the last singe element in an uneven list and that you want to collect the results into another list:
applyPairwise :: (a -> a -> b) -> [a] -> [b]
applyPairwise f (a1 : a2 : rest) = f a1 a2 : applyPairwise f rest
applyPairwise _ _ = []
Example:
> applyPairwise (+) [1..5]
[3,7]
Related Topics
Changing Values When Converting Column Type to Numeric
Output Error/Warning Log (Txt File) When Running R Script Under Command Line
Equivalent to Rowmeans() for Min()
Make Sequential Numeric Column Names Prefixed with a Letter
Accurately Converting from Character->Posixct->Character with Sub Millisecond Datetimes
Find All Date Ranges for Overlapping Start and End Dates in R
R:Pass Argument to Glm Inside an R Function
Two-Way Density Plot Combined with One Way Density Plot with Selected Regions in R
Joining Means on a Boxplot with a Line (Ggplot2)
How to Insert a Dataframe into a SQL Server Table
Removing Specific Rows from a Dataframe
Issue with Ggplot2, Geom_Bar, and Position="Dodge": Stacked Has Correct Y Values, Dodged Does Not
How to Remove Rows with 0 Values Using R
R: Ggplot Stacked Bar Chart with Counts on Y Axis But Percentage as Label
Converting Nested List (Unequal Length) to Data Frame