2017-06-16 72 views
0

對象我創建了一個功能,這需要一點時間來運行(大量的運算回事),並有我需要從這個函數返回兩個不同的輸出。這些輸入到這些輸出是相同這就是爲什麼我在同樣的功能將它們結合在一起,這樣我就不必緊縮他們的兩倍,但輸出所以在內容完全不同,並基於這種完全不同的計算方法,有沒有辦法實際將它們組合成一個解析類型的聲明。一個物體比另一個早幾十行。但我需要返回兩者,所以我認爲它必須採用某種模仿的格式:將兩個單獨的對象存儲在單個列表中,然後提取並綁定這兩個對象。返回兩個從lapply

上解決這個任何幫助,將不勝感激 - 最好不使用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)) 

功能(再次注意的功能比這要複雜得多,而我在每一個單獨的對象的計算更多的複雜和不相關的東西,而不僅僅是平均!):

func <- function(x, df){ 

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

    average_id <- temp %>% group_by(ID) %>% summarise(avg = mean(Val)) 
    average_subid <- temp %>% group_by(ID, subID) %>% summarise(avg = mean(Val)) 

    df_list <- list(avgID=average_id, avgSubID=average_subid) 

    return(df_list) 

} 

目前我已經計算使用此命令的結果,但我不確定這是否是正確的還是如何進一步抽取結果的對象存儲在這個名單(名單)之後(即我得到卡在這裏):

result <- lapply(list("A","B","C"), func, df) 

結果應該是這樣的:

> 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 

我以前使用一個for循環,並存儲在列表中的結果(即avgListID [x] < - average_id,然後綁定在一起。但我不認爲這是理想的。

在此先感謝!

回答

1
> 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 
+1

另一種選擇是'庫( dplyr); DF%>%GROUP_BY(ID,的subID)%>%總結(VAL =平均值(VAL))' – akrun

+0

嗯抱歉,我想應該已指定的輸出是如此完全不同的,並且基於這樣的完全不同的計算方法,有沒有辦法實際將它們組合成一個解析類型的聲明。 一個目的是比另一個較早線的張力。但是我需要返回兩者,所以我認爲它必須位於上面列出的某種類型的框架中。 – LyssBucks

0

如何返回一個列表,其中每個元素代表特定分組級別的平均值。例如:

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 

你也只是subID計算平均值,然後平均通過ID可以根據公式計算:

# 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)) 
+0

嗨eipi10,謝謝你的回覆。我已經更新了我的問題以包含更多的細節。 兩個對象是如此的內容完全不同,基於這樣的完全不同的計算(即不只是一個普通的),有沒有辦法實際上它們合併成一個解析還挺聲明。一個物體比另一個早幾十行。但我需要返回兩者,所以我認爲它必須採用某種模仿的格式:將兩個單獨的對象存儲在單個列表中,然後提取並綁定這兩個對象。 – LyssBucks