简体   繁体   中英

R - list of dataframes - calculate and add new rows

I have the following list of dataframes

d1 <- data.frame(var1 = 10, var2 = 20, var3 = 30)
d2 <- data.frame(var4 = 40, var5 = 50, var6 = 60)
my.list <- list(d1, d2)

> my.list
[[1]]
    var1 var2 var3
  1   10   20   30

[[2]]
    var4 var5 var6
  1   40   50   60

Now I want to add new rows to each of these dataframes that contain the following content:

values <- c(0.75, 0.5, 0.25)

d1$var1 * values[1] #new second row d1
d1$var1 * values[2] #new third row d1
d1$var1 * values[3] #new fourth row d1

This needs to be done for all $var variables in each dataframe and all dataframes in the list.

the new d1 would look like this:

    var1 var2 var3
  1   10   20   30
  2  7.5   15 22.5
  3    5   10   15
  4  2.5    5  7.5

How could I achieve this?

An option would be to loop over the list and multiply each column with the 'values' vector and rbind the original data row with the new row

lapply(my.list, function(x) rbind(x, sapply(x, `*`, values)))
#[[1]]
#  var1 var2 var3
#1 10.0   20 30.0
#2  7.5   15 22.5
#3  5.0   10 15.0
#4  2.5    5  7.5

#[[2]]
#  var4 var5 var6
#1   40 50.0   60
#2   30 37.5   45
#3   20 25.0   30
#4   10 12.5   15

Or an option with tidyverse using add_row and map

library(tidyverse)
map(my.list, ~  .x %>%
                add_row(!!! map(., `*`, values)))
#[[1]]
#  var1 var2 var3
#1 10.0   20 30.0
#2  7.5   15 22.5
#3  5.0   10 15.0
#4  2.5    5  7.5

#[[2]]
#  var4 var5 var6
#1   40 50.0   60
#2   30 37.5   45
#3   20 25.0   30
#4   10 12.5   15

Almost similar to @akrun 's, we can do(might be more computationally expensive and also has the disadvantage of forming a matrix) :

lapply(my.list,sapply,function(x) append(x,
                                do.call(`*`,list(x,values))))
[[1]]
     var1 var2 var3
[1,] 10.0   20 30.0
[2,]  7.5   15 22.5
[3,]  5.0   10 15.0
[4,]  2.5    5  7.5

[[2]]
     var4 var5 var6
[1,]   40 50.0   60
[2,]   30 37.5   45
[3,]   20 25.0   30
[4,]   10 12.5   15

Here's an interesting use of rapply() .

rapply(my.list, function(x) c(x,x*values), how = 'list')

[[1]]
[[1]]$var1
[1] 10.0  7.5  5.0  2.5

[[1]]$var2
[1] 20 15 10  5

[[1]]$var3
[1] 30.0 22.5 15.0  7.5


[[2]]
[[2]]$var4
[1] 40 30 20 10

[[2]]$var5
[1] 50.0 37.5 25.0 12.5

[[2]]$var6
[1] 60 45 30 15

You can get it back to your intended output by wrapping it in lapply(..., data.frame)

lapply(rapply(my.list, function(x) c(x,x*values), how = 'list' ), data.frame)

[[1]]
  var1 var2 var3
1 10.0   20 30.0
2  7.5   15 22.5
3  5.0   10 15.0
4  2.5    5  7.5

[[2]]
  var4 var5 var6
1   40 50.0   60
2   30 37.5   45
3   20 25.0   30
4   10 12.5   15

The rapply() itself is faster but it loses all advantages after the result is coerced back to a data.frame.

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