简体   繁体   English

在 r 中的嵌套数据帧列表上应用 function

[英]Apply function over nested list of dataframes in r

Apologies if this has been asked before - I've found a few answers related to applying functions over nested lists, but haven't managed to find one I can apply to my specific case.抱歉,如果之前有人问过这个问题 - 我找到了一些与在嵌套列表上应用函数相关的答案,但还没有找到一个我可以应用于我的具体案例的答案。

I have a list containing two lists of dataframes:我有一个包含两个数据框列表的列表:

set.seed(1)

df1 <- data.frame(x = rnorm(10), y = rnorm(10))
df2 <- data.frame(x = rnorm(10), y = rnorm(10))
df3 <- data.frame(x = rnorm(10), y = rnorm(10))

df4 <- data.frame(x = rnorm(20), y = rnorm(20))
df5 <- data.frame(x = rnorm(20), y = rnorm(20))
df6 <- data.frame(x = rnorm(20), y = rnorm(20))

lista <- list(df1, df2, df3)
listb <- list(df4, df5, df6)

list <- list(lista, listb)

I'd like to apply something like the following function over the two lists of dataframes:我想在两个数据帧列表上应用类似于以下 function 的内容:

f <- function (constant1, constant2, dfa, dfb){
  (constant1 * (sum(dfa$x) + sum(dfa$y))) + (constant2 * (sum(dfb$x) + sum(dfb$y))) 
}

So, for the list defined above, the function would use dfa = df1 and dfb = df4 in the first iteration.因此,对于上面定义的列表,function 将在第一次迭代中使用dfa = df1dfb = df4 For the second iteration, these would become dfa = df2 and dfb = df5 , and so-on.对于第二次迭代,这些将变为dfa = df2dfb = df5 ,依此类推。

With both constants set as 1 , the output should be a list containing three items:两个常量都设置为1 , output 应该是一个包含三个项目的列表:

> output
[[1]]
[1] 8.242232

[[2]]
[1] -2.19834

[[3]]
[1] 4.330664

I'm guessing I need mapply to do this, but can't work out how to call the dataframes.我猜我需要mapply来执行此操作,但无法弄清楚如何调用数据帧。

Among many other attempts, I tried the following (which throws the error $ operator is invalid for atomic vectors ):在许多其他尝试中,我尝试了以下方法(抛出错误$ operator is invalid for atomic vectors ):

output <- mapply(function(a, b, c, d) f(constant1 = a, constant2 = b, dfa = c, dfb = d),
                 a = 1, b = 1, c = list[[1]][[1]], d = list[[2]][[1]])

You can use mapply like this:您可以像这样使用mapply

mapply(function(a, b) f(constant1 = 1, constant2 = 1, dfa = a, dfb = b), 
                      list[[1]], list[[2]])
#[1]  8.242232 -2.198340  4.330664

Or perhaps better:或者也许更好:

mapply(f, list[[1]], list[[2]], MoreArgs = list(constant1 = 1, constant2 = 1))

a tidyverse solution一个tidyverse解决方案

library(tidyverse)

foo <- function(x, constant1, constant2){ 
  x %>% 
  bind_rows(.id = "gr") %>% 
  group_by(gr) %>%
  summarise(res= sum(x,y)) %>%  
  mutate(gr1 = rep(1:(n()/2), n()/(n()/2))) %>%  
  group_by(gr1) %>%  
  summarise(res=sum(res[1]*constant1,res[2]*constant2)) %>% 
  pull(res)}

foo(list, constant1 = 1, constant2 = 1)
[1]  8.242232 -2.198340  4.330664

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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