我在 R 中有一个数据框,其中包含以下列结构(规模更大):
Material_code actual_202009 actual_202010 actual_202011 pred_202009 pred_202010 pred_202011
111 30 44 24 25 52 27
112 19 70 93 23 68 100
我想向包含相应错误度量的数据帧添加新列:
|actual - pred|/ actual * 100%
获得:
Material_code actual_202009 actual_202010 actual_202011 pred_202009 pred_202010 pred_202011 MAPE_202009 MAPE_202010 MAPE_202011
111 30 44 24 25 52 27 16.67% 18.18% 12.5%
112 19 70 93 23 68 100 21.05% 2.86% 7.52%
我尝试使用 ends_with()
创建新列以选择上一列,但我没有做对。你能帮忙吗?
*** 编辑以包含更简单的方法来生成数据框
df <- data.frame(Material_code = c(111,112),
actual_202009 = c(30,19),
actual_202010 = c(44,70),
actual_202011 = c(24,93),
pred_202009 = c(25,23),
pred_202010 = c(52,68),
pred_202011 = c(27,100))
答案 0 :(得分:1)
来自 tidyverse 的更详细:
library(tidyverse)
df %>%
pivot_longer(cols = -Material_code) %>%
separate(name, into = c("type", "time"), sep = "_") %>%
pivot_wider(names_from = type) %>%
mutate(MAPE = abs(actual - pred)/actual*100) %>%
pivot_wider(values_from = c(actual, pred, MAPE),
names_from = time)
给出:
# A tibble: 2 x 10
Material_code actual_202009 actual_202010 actual_202011 pred_202009 pred_202010 pred_202011 MAPE_202009 MAPE_202010 MAPE_202011
<int> <int> <int> <int> <int> <int> <int> <dbl> <dbl> <dbl>
1 111 30 44 24 25 52 27 16.7 18.2 12.5
2 112 19 70 93 23 68 100 21.1 2.86 7.53
答案 1 :(得分:1)
如果您尝试以长格式保存数据,将会对自己有很大帮助:每列都有相同类型的数据。 你的表格是宽格式,对于excel和人类可视化非常有用,但在代码中处理起来非常麻烦。
所以您需要做的第一件事(这就是@deschen 在他们的回答中所做的)是将您的数据转换为 long,然后对其进行操作。您的数据的长版本将采用以下形式
Material_code Type Date Value
111 actual 202011 30
我将提供一个 data.table 解决方案,它与@deschen 的基本相同。您可能会喜欢它,因为它处理大数据的速度很快。
library(data.table)
setDT(df1)
df1[, melt(.SD, 1)][,
c("type", "date") := tstrsplit(variable, "_", fixed = TRUE)][,
dcast(.SD, Material_code + date ~ type)][,
mape := 100 * abs(actual - pred) / actual][]
melt(.SD, 1)
将您的表格从宽转换为长,只保留第一列作为每条记录的参考。c("type", "date") := tstrsplit(variable, "_", fixed = TRUE)
使用取自 variable
的相应值创建列类型和日期(在 melt
之后,variable
具有以前的列名称)。dcast(.SD, Material_code + date ~ type)
再次将长表转换为宽表。这一次,Material_code
和 date
将保留在列中,而 type
将被转换为新列 actual
和 pred
。:=
是赋值运算符。它创建变量 mape
并分配结果值。[]
实际上并不需要。有没有所以结果打印到屏幕上。如果您不需要将新表格打印到屏幕上,请忽略它。答案 2 :(得分:0)
获取所有'actual'
和'pred'
列的列名,您可以直接对其进行所有数学计算。
actual_cols <- sort(grep('actual', names(df), value = TRUE))
pred_cols <- sort(grep('pred', names(df), value = TRUE))
new_cols <- sub('pred', 'MAPE', pred_cols)
df[new_cols] <- abs(df[actual_cols] - df[pred_cols])/df[actual_cols] * 100
df
# Material_code actual_202009 actual_202010 actual_202011 pred_202009
#1 111 30 44 24 25
#2 112 19 70 93 23
# pred_202010 pred_202011 MAPE_202009 MAPE_202010 MAPE_202011
#1 52 27 16.7 18.18 12.50
#2 68 100 21.1 2.86 7.53
数据
df <- structure(list(Material_code = 111:112, actual_202009 = c(30L,
19L), actual_202010 = c(44L, 70L), actual_202011 = c(24L, 93L
), pred_202009 = c(25L, 23L), pred_202010 = c(52L, 68L), pred_202011 = c(27L,
100L)), class = "data.frame", row.names = c(NA, -2L))