【问题标题】:How to use cumsum-Lapply when i+1 column is needed?需要 i+1 列时如何使用 cumsum-Lapply?
【发布时间】:2019-05-02 12:28:39
【问题描述】:

我目前正在处理一个相当大的文件,其中包含几台机器(大约 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  

我的目的是为每个设备获取一个新列的每次停止/运行的累积产量(可能在新的 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))

但我不知道如何概括它,因为我每次都需要一个不同的列用于组,而我目前无法用列索引替换列的名称...

你知道我该怎么做吗?

【问题讨论】:

  • 不清楚您的数据集名称的含义。您能否更完整地“描绘”您的预期结果?
  • 澄清一下,这个过程是你取累计和,但每次stops 列达到 -1 时重置?
  • 可以从1-1 再到1 等吗?
  • 例如,nx 表示“设备 n°x”。我有生产设备n°x“nx_prod”,也有运行期“nx_stops”。
  • 第三栏的名字无所谓,随便选的

标签: r group-by lapply cumsum


【解决方案1】:

您可以根据每个列名的前缀进行拆分,并在那里应用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

【讨论】:

    【解决方案2】:

    我们可以先分离以"prod""stop" 结尾的列,然后为每个组使用mapplyavecumsum 并创建新列。

    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
    

    【讨论】:

    • 似乎也可以,但比 Sotos 的解决方案需要更多时间。然而,这个不需要进一步加入数据帧。谢谢
    猜你喜欢
    • 2019-10-25
    • 1970-01-01
    • 1970-01-01
    • 2021-05-19
    • 2022-01-22
    • 2015-09-29
    • 2014-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多