2015-11-09 32 views
0

我有一個小數據幀,其中包含10個週期的值。我想總結每個值和預測值之間的絕對差值(絕對誤差)。數據幀的總和絕對差值

列標誌:P1,P2,P3,..... P10

值:3,4,3 ...... 7(見下文數據)

預測值= 5 (它不總是5)

「error」公式= | 3-5 | + | 4-5 | + | 3-5 | + .... + | 7-5 |

> data 
    cust P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 predict error 
1  A 1 1 1 1 1 1 1 1 1 1  5  ? 
2  B 3 3 3 3 3 3 3 3 3 3  5  ? 
3  C 1 1 1 1 1 3 3 3 3 3  5  ? 
4  D 1 0 1 0 1 0 1 0 1 0  5  ? 
5  E 1 0 0 1 0 0 1 0 0 1  5  ? 
6  F 1 3 1 3 1 3 1 3 1 3  5  ? 
7  G 5 5 5 5 5 5 5 5 5 5  5  ? 
8  H 8 8 8 8 8 8 8 8 8 8  5  ? 
9  I 5 5 5 5 5 8 8 8 8 8  5  ? 
10 J 5 0 5 0 5 0 5 0 5 0  5  ? 
11 K 5 0 0 5 0 0 5 0 0 5  5  ? 
12 L 5 8 5 8 5 8 5 8 5 8  5  ? 

我可以做一個長格式的計算,但我不想重做不同大小的數據冗長凌亂的公式。最終的數據集將有更多的時間段和客戶,所以我需要一個適用於不同大小數據幀的公式/函數。我希望得到一些幫助。

我知道這可以使用預測包來完成,但我需要從底部構建它,以便我可以對結果做其他事情。

回答

2

我認爲你厭惡涉及長時間回答的很多原因是因爲代碼像其他兩個答案已經出現在這裏。他們完成這項工作 - 但幾乎不可讀。

使用dplyr & tidyr,生產普通以及可讀代碼:

library(dplyr) 
library(tidyr) 
library(ggplot2) 

# read data in 
dfX = as_data_frame(read.table(textConnection(" 
       cust P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 predict error 
1  A 1 1 1 1 1 1 1 1 1 1  5  ? 
       2  B 3 3 3 3 3 3 3 3 3 3  5  ? 
       3  C 1 1 1 1 1 3 3 3 3 3  5  ? 
       4  D 1 0 1 0 1 0 1 0 1 0  5  ? 
       5  E 1 0 0 1 0 0 1 0 0 1  5  ? 
       6  F 1 3 1 3 1 3 1 3 1 3  5  ? 
       7  G 5 5 5 5 5 5 5 5 5 5  5  ? 
       8  H 8 8 8 8 8 8 8 8 8 8  5  ? 
       9  I 5 5 5 5 5 8 8 8 8 8  5  ? 
       10 J 5 0 5 0 5 0 5 0 5 0  5  ? 
       11 K 5 0 0 5 0 0 5 0 0 5  5  ? 
       12 L 5 8 5 8 5 8 5 8 5 8  5  ?"), 
       header = TRUE, stringsAsFactors = FALSE)) 

# melt & compute error 
dfXErr = dfX %>% 
    select(-error) %>%      
    gather(period, actual, -cust, -predict) %>% 
    group_by(cust) %>% 
    summarize(mape = mean(abs(actual - predict))) 

# join back to original data (if required) 
inner_join(dfX, dfXErr, by = "cust") 
+0

所有回覆的工作,感謝大家的幫助!我認爲dplyr是要走的路,它更容易閱讀。我打算更熟悉它並更多地使用它。再次感謝! – Paul

0
data$error <- apply(apply(data[,-c(1,12)], 2, function(x) abs(x - data[,12])),1, sum) 
data 
    cust P1 P2 P3 P4 P5 P6 P7 P8 P9 P10 predict error 
1  A 1 1 1 1 1 1 1 1 1 1  5 40 
2  B 3 3 3 3 3 3 3 3 3 3  5 20 
3  C 1 1 1 1 1 3 3 3 3 3  5 30 
4  D 1 0 1 0 1 0 1 0 1 0  5 45 
5  E 1 0 0 1 0 0 1 0 0 1  5 46 
6  F 1 3 1 3 1 3 1 3 1 3  5 30 
7  G 5 5 5 5 5 5 5 5 5 5  5  0 
8  H 8 8 8 8 8 8 8 8 8 8  5 30 
9  I 5 5 5 5 5 8 8 8 8 8  5 15 
10 J 5 0 5 0 5 0 5 0 5 0  5 25 
11 K 5 0 0 5 0 0 5 0 0 5  5 30 
12 L 5 8 5 8 5 8 5 8 5 8  5 15 
+0

感謝。雖然我更喜歡不叫出特定的位置(如[,-c(1,12)] ...),但這樣做會起作用,因爲如果我添加句點,會使它變得很尷尬。 – Paul

3

這應該做的伎倆

data$error <- rowSums(abs(data[,grepl("^P\\d+", names(data))] - data$predict)) 

它假定所有的時間開始以「P」後面跟着一個或多個數字。

+0

謝謝,這也適用。 – Paul

+0

好的答案,簡潔明瞭 – user20650

0

使用A溶液for循環(可能比其它解決方案更慢):

df = data.frame(P1=c(1,2,3),P2=c(4,5,6),predict=c(5,5,6)) 
numLabels = 2 
df$error = 0 
for(i in 1:numLabels) { 
    df$error = df$error + abs(df[,paste0("P",i)] - df$predict) 
} 
+0

謝謝,這個工程。 – Paul