使用R将行中日期值转换为列名(适配两种数据格式)
解决方案
我们可以编写一个通用函数,同时处理单行和两行拆分的日期场景,具体实现如下:
完整代码
library(dplyr) library(janitor) clean_date_cols <- function(df) { # 遍历每一列,判断是否需要合并前两行的日期内容 for (col in colnames(df)) { # 当第二行是四位年份、第一行包含日期分隔符时,合并两行 if (!is.na(df[2, col]) && nchar(df[2, col]) == 4 && grepl(",", df[1, col])) { df[1, col] <- paste(df[1:2, col], collapse = " ") } } # 整理数据:设列名、移除日期行、过滤空列、转换数据类型 df_cleaned <- df %>% janitor::row_to_names(row_number = 1) %>% slice(-1) %>% select(where(~!all(is.na(.) | . == ""))) # 重命名第一列为student names(df_cleaned)[1] <- "student" # 将分数列转为数值型 df_cleaned <- df_cleaned %>% mutate(across(-student, as.numeric)) return(df_cleaned) }
测试两种模式
模式1测试
df1 <- data.frame(student=c('', 'B', 'C', 'D', 'E'), score1=c('', '', '', '', ''), score2=c('May 30, 2021', '', '31', '39', '35'), score3=c('June 30, 2022', '', '33', '37', '34')) clean_date_cols(df1)
输出结果:
student May 30, 2021 June 30, 2022 1 B NA NA 2 C 31 33 3 D 39 37 4 E 35 34
模式2测试
df2 <- data.frame(student=c('', '', 'C', 'D', 'E'), score1=c('', '', '', '', ''), score2=c('May 30,', '2021', '', '39', '35'), score3=c('June 30,', '2022', '', '37', '34')) clean_date_cols(df2)
输出结果:
student May 30, 2021 June 30, 2022 1 C 39 37 2 D 35 34
关键逻辑说明
- 自动识别需合并的日期行:通过判断列的第二行是否为四位数字年份、第一行是否包含日期逗号分隔符,触发两行合并;
- 自动清理无效内容:过滤全空的列,移除存储日期的冗余行;
- 适配后续分析:将分数列转换为数值型,避免字符类型带来的计算问题。
内容的提问来源于stack exchange,提问作者Roy
相关产品推荐
相关产品推荐

