数据帧中的总和绝对差异

Sum absolute difference in dataframe

我有一个包含 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     ?

我可以用长格式进行计算,但我不想为不同大小的数据重做长而杂乱的公式。最终的数据集将有更多的时期和客户,所以我需要一个适用于不同大小的数据框的公式/函数。我将不胜感激。

我知道这可以使用预测包来完成,但我需要从头开始构建它,以便我可以用结果做其他事情。

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

这应该可以解决问题

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

它假定所有句点都以 "P" 开头,后跟一位或多位数字。

我认为您厌恶涉及 melt 太长的答案的很多原因是因为此处出现的其他两个答案之类的代码。他们完成了工作——但实际上不可读。

使用 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") 

使用 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)
}