R 从lappy返回两个对象

R 从lappy返回两个对象,r,function,loops,dplyr,lapply,R,Function,Loops,Dplyr,Lapply,我已经创建了一个运行需要一段时间的函数(大量的处理正在进行),我需要从这个函数返回两个不同的输出。这些输出的输入是相同的,这就是为什么我将它们组合在同一个函数中,这样我就不必对它们进行两次运算,但是输出的内容完全不同,并且基于完全不同的计算,因此没有办法将它们组合成一个类似解析的语句。一个对象比另一个对象早几十行。但我需要同时返回这两个对象,所以我认为它必须采用某种类似的格式:将两个单独的对象存储在一个列表中,lappy,然后提取并rbind这两个对象 如果您能提供解决方案,我们将不胜感激——最

我已经创建了一个运行需要一段时间的函数(大量的处理正在进行),我需要从这个函数返回两个不同的输出。这些输出的输入是相同的,这就是为什么我将它们组合在同一个函数中,这样我就不必对它们进行两次运算,但是输出的内容完全不同,并且基于完全不同的计算,因此没有办法将它们组合成一个类似解析的语句。一个对象比另一个对象早几十行。但我需要同时返回这两个对象,所以我认为它必须采用某种类似的格式:将两个单独的对象存储在一个列表中,lappy,然后提取并rbind这两个对象

如果您能提供解决方案,我们将不胜感激——最好不要使用for循环或data.table。Dplyr解决方案很好

一些虚拟数据:

df <- data.frame(ID = c(rep("A",10), rep("B", 10), rep("C", 10)),
                 subID = c(rep("U", 5),rep("V", 5),rep("W", 5),rep("X", 5),rep("Y", 5),rep("Z", 5)),
                   Val = c(1,6,3,8,6,5,2,4,7,20,4,2,3,5,7,3,2,5,7,12,5,3,7,1,6,1,34,9,5,3))
我以前使用过for循环并将结果存储在列表中(即avgListID[x]
>average\u ID
>平均值
第1组x
1 A 6.2
2B5.0
3 C 7.4
>平均值
>平均值
第1组,第2组
1 A U 4.8
2 A V 7.6
3 B W 4.2
4b X 5.8
5 C Y 4.4
6cz10.4

返回一个列表,其中每个元素表示特定分组级别的平均值。例如:

library(tidyverse)

fnc = function(groups=NULL, data=df) {

  groups=as.list(groups)

  data %>% 
    group_by_(.dots=groups) %>%
    summarise(avg=mean(Val))
}

list(Avg_Overall=NULL, Avg_by_ID="ID", Avg_by_SubID=c("ID","subID")) %>% 
  map(~fnc(.x))

我意识到这有点陈旧,但既然两个答案似乎都没有达到目的,那么这又如何呢?将函数分成两部分,并在
lappy
中运行每个函数,返回列表列表

library(dplyr)

df <- data.frame(ID = c(rep("A",10), rep("B", 10), rep("C", 10)),
                 subID = c(rep("U", 5),rep("V", 5),rep("W", 5),rep("X", 5),rep("Y", 5),rep("Z", 5)),
                 Val = c(1,6,3,8,6,5,2,4,7,20,4,2,3,5,7,3,2,5,7,12,5,3,7,1,6,1,34,9,5,3))

subfunc1 <- function(temp){
  return(temp %>% group_by(ID) %>% summarise(avg = mean(Val)))
}

subfunc2 <- function(temp){
  return(temp %>% group_by(ID, subID) %>% summarise(avg = mean(Val)))
}

func <- function(x, df){

  temp <- filter(df, ID == x)

  df_list <- list(avgID=subfunc1(temp), avgSubID=subfunc2(temp))

  return(df_list)

}

result <- lapply(list("A","B","C"), func, df)
库(dplyr)
df%汇总(平均值=平均值(Val)))
}
子基金2%组按(ID,子ID)%>%汇总(平均值=平均值(Val)))
}

func另一个选项是
库(dplyr);df%>%group_by(ID,subID)%>%summary(Val=mean(Val))
Hmm对不起,我想我应该指定输出是完全不同的,并且基于完全不同的计算,因此没有办法将它们组合成一个解析类语句。一个对象比另一个对象早几十行。但我需要返回两者,所以我认为它必须是在我上面列出的某种类型的框架中。嗨,eipi10,谢谢你的回复。我更新了我的问题,增加了一些细节。这两个对象在内容上完全不同,并且基于完全不同的计算(即不只是平均值),因此无法将它们实际组合成一个类似于解析的语句。一个对象比另一个对象早几十行。但我需要同时返回这两个对象,所以我认为它必须采用某种类似的格式:将两个单独的对象存储在一个列表中,lappy,然后提取并rbind这两个对象。这就是我想要的!谢谢:)
> average_ID
  ID avg
1  A 6.2
2  B 5.0
3  C 7.4


> average_subID
  ID subID   avg
1  A     U   4.8
2  A     V   7.6
3  B     W   4.2
4  B     X   5.8
5  C     Y   4.4
6  C     Z  10.4
> average_ID <- aggregate(df$Val, by = list(df$ID), FUN = mean)
> 
> average_ID
  Group.1   x
1       A 6.2
2       B 5.0
3       C 7.4
> average_subID <- aggregate(df$Val, by = list(df$ID,df$subID), FUN = mean)
> 
> average_subID
  Group.1 Group.2    x
1       A       U  4.8
2       A       V  7.6
3       B       W  4.2
4       B       X  5.8
5       C       Y  4.4
6       C       Z 10.4
library(tidyverse)

fnc = function(groups=NULL, data=df) {

  groups=as.list(groups)

  data %>% 
    group_by_(.dots=groups) %>%
    summarise(avg=mean(Val))
}

list(Avg_Overall=NULL, Avg_by_ID="ID", Avg_by_SubID=c("ID","subID")) %>% 
  map(~fnc(.x))
$Avg_Overall
# A tibble: 1 x 1
    avg
  <dbl>
1   6.2

$Avg_by_ID
# A tibble: 3 x 2
      ID   avg
  <fctr> <dbl>
1      A   6.2
2      B   5.0
3      C   7.4

$Avg_by_SubID
# A tibble: 6 x 3
# Groups:   ID [?]
      ID  subID   avg
  <fctr> <fctr> <dbl>
1      A      U   4.8
2      A      V   7.6
3      B      W   4.2
4      B      X   5.8
5      C      Y   4.4
6      C      Z  10.4
# Average by subID
avg = df %>% group_by(ID, subID) %>%
  summarise(n = n(),
            avg = mean(Val))

# Average by ID
avg %>% 
  group_by(ID) %>% 
  summarise(avg = sum(avg*n)/sum(n))

# Overall average
avg %>% 
  ungroup %>%
  summarise(avg = sum(avg*n)/sum(n))
library(dplyr)

df <- data.frame(ID = c(rep("A",10), rep("B", 10), rep("C", 10)),
                 subID = c(rep("U", 5),rep("V", 5),rep("W", 5),rep("X", 5),rep("Y", 5),rep("Z", 5)),
                 Val = c(1,6,3,8,6,5,2,4,7,20,4,2,3,5,7,3,2,5,7,12,5,3,7,1,6,1,34,9,5,3))

subfunc1 <- function(temp){
  return(temp %>% group_by(ID) %>% summarise(avg = mean(Val)))
}

subfunc2 <- function(temp){
  return(temp %>% group_by(ID, subID) %>% summarise(avg = mean(Val)))
}

func <- function(x, df){

  temp <- filter(df, ID == x)

  df_list <- list(avgID=subfunc1(temp), avgSubID=subfunc2(temp))

  return(df_list)

}

result <- lapply(list("A","B","C"), func, df)
n <- length(result[[1]]) # assuming all lists in result have the same length
result <- lapply(1:n, function(i) lapply(result, "[[", i))