钉钉导出的考勤时间表,每个员工一行数据,每天所有的打卡时间为一列。根据需求,计算纯工时:去除午休(12:00-13:30)和晚餐(如有,18:00-19:00)的工作时间。
library(tidyverse)
dt = readxl::read_xlsx("test.xlsx")
names(dt) = c("姓名", paste0("date", 1:30))
DT::datatable(dt |> select(1, 16:20))
请出 ChatGPT-4o 「帮助」打工人计算工时(单位:小时)1:
# 创建一个函数来计算每日出勤时间
calculate_attendance_time <- function(times) {
# 将日期数据转为数值秒数
second = function(x) {
hm(x) |> as.numeric()
}
times = second(times)
noon = second("12:00")
afternoon_start = second("13:30")
evening_start = second("18:00")
evening_end = second("19:00")
latest_time = max(times)
# 计算上午出勤时间
morning_start <- min(times)
morning_end <- ifelse(morning_start < noon, noon, morning_start)
morning_time <- morning_end - morning_start
# 计算下午出勤时间
afternoon_start_time <- ifelse(latest_time > afternoon_start, afternoon_start, latest_time)
afternoon_end_time = ifelse(latest_time > evening_end, evening_start, latest_time)
afternoon_time <- afternoon_end_time - afternoon_start_time
# 计算晚上出勤时间
evening_time <- ifelse(latest_time > evening_end, latest_time - evening_end, 0)
tibble(
morning = morning_time / 3600,
afternoon = afternoon_time / 3600,
evening = evening_time / 3600,
total = (morning_time + afternoon_time + evening_time) / 3600
)
}
测试 calculate_attendance_time()
函数效果:
c("09:00", "21:00") |> calculate_attendance_time() # 福报
#> # A tibble: 1 × 4
#> morning afternoon evening total
#> <dbl> <dbl> <dbl> <dbl>
#> 1 3 4.5 2 9.5
c("08:30", "22:16") |> calculate_attendance_time() # 至尊打工人
#> # A tibble: 1 × 4
#> morning afternoon evening total
#> <dbl> <dbl> <dbl> <dbl>
#> 1 3.5 4.5 3.27 11.3
c("08:59", "18:24", "21:00", "21:01") |> calculate_attendance_time() # 卡点
#> # A tibble: 1 × 4
#> morning afternoon evening total
#> <dbl> <dbl> <dbl> <dbl>
#> 1 3.02 4.5 2.02 9.53
c("8:55", "18:01") |> calculate_attendance_time() # 你的生活我的梦
#> # A tibble: 1 × 4
#> morning afternoon evening total
#> <dbl> <dbl> <dbl> <dbl>
#> 1 3.08 4.52 0 7.6
c("10:00", "17:30") |> calculate_attendance_time() # 宇宙尽头
#> # A tibble: 1 × 4
#> morning afternoon evening total
#> <dbl> <dbl> <dbl> <dbl>
#> 1 2 4 0 6
芜湖!没问题,批量计算工作日纯工时:
dt |>
pivot_longer(2:31, names_to = "date", values_to = "check") |>
drop_na(check) |>
mutate(
res = map(str_split(check, " \r\n"), calculate_attendance_time)
) |>
unnest_wider(res) |>
mutate(across(4:7, \(x) round(x, 2))) |>
select(-check)
#> # A tibble: 42 × 6
#> 姓名 date morning afternoon evening total
#> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
#> 1 甲 date1 2.93 4.5 2 9.43
#> 2 甲 date2 3 4.5 2.7 10.2
#> 3 甲 date3 2.93 4.5 1.2 8.63
#> 4 甲 date7 2.95 4.5 0.77 8.22
#> 5 甲 date8 2.93 4.5 2.02 9.45
#> 6 甲 date9 3 4.5 2.1 9.6
#> 7 甲 date11 3 4.5 1.7 9.2
#> 8 甲 date12 2.95 4.5 0.13 7.58
#> 9 甲 date15 3 4.5 1.5 9
#> 10 甲 date16 2.95 4.5 1.57 9.02
#> # ℹ 32 more rows
-
<-
赋值的是 GPT 写的,=
赋值的是俺自己写的。 ↩︎