简体   繁体   中英

Passing different arguments to function for each dataframe in a list

Here's a simplified example of my data:

I have a list of dataframes

set.seed(1)
data1 <- data.frame(A = sample(1:10))
data2 <- data.frame(A = sample(1:10))
data3 <- data.frame(A = sample(1:10))
data4 <- data.frame(A = sample(1:10))
list1 <- list(data1, data2, data3, data4)

And a dataframe containing the same number of values as there are dataframes in list1

data5 <- data.frame(B = c(10, 20, 30, 40))

I would like to create a new column C in each of the dataframes within list1 where:

C = A * (B/nrow(A))

with the value for B coming from data5 , so that B = 10 for the first dataframe in list1 (ie data1 ), and B = 20 for the second dataframe data2 and so on.

From what I've read, mapply is probably the solution, but I'm struggling to work out how to specify a single value of B across all rows in each of the dataframes in list1 .

Any suggestions would be hugely appreciated.

You need to use Map to loop on different vectors or list in parallel :

Map(function(df, B) transform(df, C = A*(B/nrow(df))),list1,data5$B)
#> [[1]]
#>     A  C
#> 1   8  8
#> 2  10 10
#> 3   1  1
#> 4   6  6
#> 5   7  7
#> 6   9  9
#> 7   3  3
#> 8   4  4
#> 9   2  2
#> 10  5  5
#> 
#> [[2]]
#>     A  C
#> 1  10 20
#> 2   3  6
#> 3   2  4
#> 4   1  2
#> 5   9 18
#> 6   4  8
#> 7   6 12
#> 8   5 10
#> 9   8 16
#> 10  7 14
#> 
#> [[3]]
#>     A  C
#> 1   5 15
#> 2   7 21
#> 3   1  3
#> 4   4 12
#> 5   2  6
#> 6   6 18
#> 7  10 30
#> 8   3  9
#> 9   8 24
#> 10  9 27
#> 
#> [[4]]
#>     A  C
#> 1   3 12
#> 2   9 36
#> 3   6 24
#> 4   4 16
#> 5   2  8
#> 6   1  4
#> 7  10 40
#> 8   5 20
#> 9   7 28
#> 10  8 32

You can be a bit more compact using tidyverse :

library(tidyverse)
map2(list1, data5$B, ~mutate(.x, C = A*(.y/nrow(.x))))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM