当需要第 i+1 列时,如何使用 cumsum-Lapply?
How to use cumsum-Lapply when i+1 column is needed?
我目前正在处理一个相当大的文件,其中包含 stops/go 几台机器(大约 60 台)+ 它们的长期生产(超过 60 000 行)。
停止由“-1”索引并按“1”索引:
**Date n1_prod n1_stops n2_prod n2_stops n3_prod
1 2011-12-13 00:00:00 2 1 0 -1 14
2 2011-12-13 01:00:00 10 1 -10 -1 24
3 2011-12-13 02:00:00 24 1 -5 -1 23
4 2011-12-13 03:00:00 25 1 0 -1 22
5 2011-12-13 04:00:00 23 1 12 1 13
6 2011-12-13 05:00:00 0 -1 11 1 17
7 2011-12-13 06:00:00 -2 -1 21 1 18
我的目的是为每个设备获得每个 stop/go 的新列累计产量(可能在新的 df 上)。例如,对于设备 n°1,它将是:
**Date n1_prod n1_stops n1_agprod
1 2011-12-13 00:00:00 2 1 2
2 2011-12-13 01:00:00 10 1 12
3 2011-12-13 02:00:00 24 1 36
4 2011-12-13 03:00:00 25 1 61
5 2011-12-13 04:00:00 23 1 84
6 2011-12-13 05:00:00 0 -1 0
7 2011-12-13 06:00:00 -2 -1 -2
对于一列,我可以使用 :
得到想要的结果
df<-as_tibble(df)%>%
group_by(n1_stops) %>%
dplyr::mutate(n1_agprod= cumsum(n1_prod))
但我不知道如何概括它,因为每次组都需要不同的列,而且我目前无法用列索引替换列的名称...
你知道我该怎么做吗?
您可以根据每个列名的前缀进行拆分,并在那里应用 cumsum
,即
sapply(split.default(df[-1], sub('_.*','',names(df[-1]))),
function(i) ave(i[[1]], i[[2]], FUN = cumsum))
# n1 n2
#[1,] 2 0
#[2,] 12 -10
#[3,] 36 -15
#[4,] 61 -15
#[5,] 84 12
#[6,] 0 23
#[7,] -2 44
我们可以先将以"prod"
和"stop"
结尾的列分开,然后对每个组使用mapply
和ave
到cumsum
并创建新的列。
prod_cols <- grep("prod$", names(df))
stop_cols <- grep("stops$", names(df))
df[paste0("agprod", 1:length(prod_cols))] <-
mapply(ave, df[prod_cols], df[stop_cols], MoreArgs = list(FUN = cumsum))
df
# Date n1_prod n1_stops n2_prod n2_stops agprod1 agprod2
#1 2011-12-1300:00:00 2 1 0 -1 2 0
#2 2011-12-1301:00:00 10 1 -10 -1 12 -10
#3 2011-12-1302:00:00 24 1 -5 -1 36 -15
#4 2011-12-1303:00:00 25 1 0 -1 61 -15
#5 2011-12-1304:00:00 23 1 12 1 84 12
#6 2011-12-1305:00:00 0 -1 11 1 0 23
#7 2011-12-1306:00:00 -2 -1 21 1 -2 44
我目前正在处理一个相当大的文件,其中包含 stops/go 几台机器(大约 60 台)+ 它们的长期生产(超过 60 000 行)。 停止由“-1”索引并按“1”索引:
**Date n1_prod n1_stops n2_prod n2_stops n3_prod
1 2011-12-13 00:00:00 2 1 0 -1 14
2 2011-12-13 01:00:00 10 1 -10 -1 24
3 2011-12-13 02:00:00 24 1 -5 -1 23
4 2011-12-13 03:00:00 25 1 0 -1 22
5 2011-12-13 04:00:00 23 1 12 1 13
6 2011-12-13 05:00:00 0 -1 11 1 17
7 2011-12-13 06:00:00 -2 -1 21 1 18
我的目的是为每个设备获得每个 stop/go 的新列累计产量(可能在新的 df 上)。例如,对于设备 n°1,它将是:
**Date n1_prod n1_stops n1_agprod
1 2011-12-13 00:00:00 2 1 2
2 2011-12-13 01:00:00 10 1 12
3 2011-12-13 02:00:00 24 1 36
4 2011-12-13 03:00:00 25 1 61
5 2011-12-13 04:00:00 23 1 84
6 2011-12-13 05:00:00 0 -1 0
7 2011-12-13 06:00:00 -2 -1 -2
对于一列,我可以使用 :
得到想要的结果df<-as_tibble(df)%>%
group_by(n1_stops) %>%
dplyr::mutate(n1_agprod= cumsum(n1_prod))
但我不知道如何概括它,因为每次组都需要不同的列,而且我目前无法用列索引替换列的名称...
你知道我该怎么做吗?
您可以根据每个列名的前缀进行拆分,并在那里应用 cumsum
,即
sapply(split.default(df[-1], sub('_.*','',names(df[-1]))),
function(i) ave(i[[1]], i[[2]], FUN = cumsum))
# n1 n2
#[1,] 2 0
#[2,] 12 -10
#[3,] 36 -15
#[4,] 61 -15
#[5,] 84 12
#[6,] 0 23
#[7,] -2 44
我们可以先将以"prod"
和"stop"
结尾的列分开,然后对每个组使用mapply
和ave
到cumsum
并创建新的列。
prod_cols <- grep("prod$", names(df))
stop_cols <- grep("stops$", names(df))
df[paste0("agprod", 1:length(prod_cols))] <-
mapply(ave, df[prod_cols], df[stop_cols], MoreArgs = list(FUN = cumsum))
df
# Date n1_prod n1_stops n2_prod n2_stops agprod1 agprod2
#1 2011-12-1300:00:00 2 1 0 -1 2 0
#2 2011-12-1301:00:00 10 1 -10 -1 12 -10
#3 2011-12-1302:00:00 24 1 -5 -1 36 -15
#4 2011-12-1303:00:00 25 1 0 -1 61 -15
#5 2011-12-1304:00:00 23 1 12 1 84 12
#6 2011-12-1305:00:00 0 -1 11 1 0 23
#7 2011-12-1306:00:00 -2 -1 21 1 -2 44