【问题标题】:Effcient shifting in R data.table with missing valuesR data.table 中缺少值的有效移位
【发布时间】:2021-03-13 12:51:36
【问题描述】:

我有一个包含以下三个变量的 data.table

  1. receptionist = 接待人员的身份证
  2. week.no = 本周编号(1 表示第一周)
  3. absent.thisweek = 本周缺勤天数

请注意,我们只有接待员来上班的那几周的数据,如果缺少一周意味着该人该周缺席

例如,我们有两个使用这种工作模式的接待处 1 和 2:

dt <- data.table(receptionist =  c(1,1,1,2,2,2,2), week.no = c(1,3,4,5,8,10,11), absent.thisweek = c(1,2,3,4,5,6,6))
>dt receptionist week.no absent.thisweek
1:            1       1               1
2:            1       3               2
3:            1       4               3
4:            2       5               4
5:            2       8               5
6:            2      10               6
7:            2      11               6

第 1 步:我需要找出接待员下周缺席的天数,为此,如果数据中提供了该信息,我将缺席的天数移动一周(周),请注意接待员的周数不来,这个值是NA,我的数据集有100万行,这是效率最低的部分。

dt[order(receptionist, week.no), absent.nextweek := dt$absent.thisweek[dt$receptionist==receptionist & dt$week.no==week.no+1], by = .(receptionist, week.no)]
>dt receptionist week.no absent.thisweek absent.nextweek
1:            1       1               1              NA
2:            1       3               2               3
3:            1       4               3              NA
4:            2       5               4              NA
5:            2       8               5              NA
6:            2      10               6               6
7:            2      11               6              NA

第 2 步:如果数据缺失,则必须缺失 7 天。上周,我们将缺席.nextweek = NA

dt[is.na(absent.nextweek) & week.no != max(week.no, na.rm=T), absent.nextweek:=7]
   
>dt receptionist week.no absent.thisweek absent.nextweek
1:            1       1               1               7
2:            1       3               2               3
3:            1       4               3               7
4:            2       5               4               7
5:            2       8               5               7
6:            2      10               6               6
7:            2      11               6              NA

我面临两个问题: - 在第 1 步中,它非常低效且需要很长时间(大约 1 小时)才能运行 - 在第 2 步中,第 3 行的最后一列应该有 NA,事实并非如此

任何提高效率的建议(最好是data.table)都会非常有帮助,并指出步骤2中的错误。

正确答案是:

>dt receptionist week.no absent.thisweek absent.nextweek
1:            1       1               1               7
2:            1       3               2               3
3:            1       4               3               NA
4:            2       5               4               7
5:            2       8               5               7
6:            2      10               6               6
7:            2      11               6              NA

【问题讨论】:

    标签: r dataframe data.table shift lead


    【解决方案1】:

    从头开始考虑问题,也许你可以直接用fifelse()shift()做这个?

    # We assume data is ordered by week. Otherwise you can run 
    # setorder(dt, receptionist, week.no)
    
    dt[, 
       absent.nextweek := 
         fifelse(week.no+1L == shift(week.no, -1L),  shift(absent.thisweek, -1L), 7),
       by = receptionist]
    
    
    #    receptionist week.no absent.thisweek absent.nextweek
    # 1:            1       1               1               7
    # 2:            1       3               2               3
    # 3:            1       4               3              NA
    # 4:            2       5               4               7
    # 5:            2       8               5               7
    # 6:            2      10               6               6
    # 7:            2      11               6              NA
    

    【讨论】:

    • 我检查了解决方案,它运行良好且高效。我又写了一个问题——为什么 max() 不起作用,而我使用我的代码在第 3 列中得到 7? @sindri_baldur
    • 我似乎是因为您指的是最大整体而不是按组。
    • 谢谢。我已经接受了答案。顺便说一句,通过 = .(receptionist) 编写代码不会改变 max 的结果。 @sindri_baldur
    猜你喜欢
    • 1970-01-01
    • 2018-10-10
    • 2013-12-30
    • 2023-04-01
    • 2017-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    相关资源
    最近更新 更多