在R中按对应日期排序数据框每行的两列名称
问题描述
我有两个R数据框:
- df1包含两列名称数据:
df1 <- structure(list(Col1 = c("Luis", "Pedro", "John", "Ingrid"), Col2 = c("Raul", "Maria", "Chris", "Lia")), class = "data.frame", row.names = c(NA, -4L))
- df2存储每个名称对应的日期:
df2 <- structure(list(Name = c("Luis", "Pedro", "John", "Ingrid","Raul", "Maria", "Chris", "Lia"), Date = c("10/05/22","04/05/22", "03/05/22", "07/05/22","01/05/22","06/05/22", "05/05/22","02/05/22")), class = "data.frame", row.names = c(NA, -8L))
数据框展示:
df1:
Col1 Col2 1 Luis Raul 2 Pedro Maria 3 John Chris 4 Ingrid Lia
df2:
Name Date 1 Luis 10/05/22 2 Pedro 04/05/22 3 John 03/05/22 4 Ingrid 07/05/22 5 Raul 01/05/22 6 Maria 06/05/22 7 Chris 05/05/22 8 Lia 02/05/22
需求:对df1的每一行处理,将对应日期更早的名称放在Col1,日期较晚的放在Col2,预期结果:
Col1 Col2 1 Raul Luis 2 Pedro Maria 3 John Chris 4 Lia Ingrid
解决方案
方法1:使用dplyr + tidyr(tidyverse风格)
先将df2的字符串日期转换为可比较的日期类型,再逐行判断并调整列值:
library(dplyr) library(tidyr) # 转换日期格式为Date类型 df2 <- df2 %>% mutate(Date = as.Date(Date, format = "%d/%m/%y")) # 处理df1 result <- df1 %>% rowwise() %>% mutate( # 获取当前行两个名称对应的日期 date_col1 = df2$Date[df2$Name == Col1], date_col2 = df2$Date[df2$Name == Col2], # 根据日期大小重新分配Col1和Col2 Col1 = if(date_col1 < date_col2) Col1 else Col2, Col2 = if(date_col1 < date_col2) Col2 else Col1 ) %>% select(-date_col1, -date_col2) %>% # 移除临时列 ungroup() print(result)
方法2:Base R实现
无需额外包,直接通过循环和命名向量匹配日期:
# 转换df2的日期格式 df2$Date <- as.Date(df2$Date, format = "%d/%m/%y") # 创建名称-日期的命名向量,方便快速匹配 name_to_date <- setNames(df2$Date, df2$Name) # 逐行检查并交换列值 for (row_idx in seq(nrow(df1))) { name1 <- df1$Col1[row_idx] name2 <- df1$Col2[row_idx] if (name_to_date[name1] > name_to_date[name2]) { # 交换Col1和Col2的值 df1[row_idx, c("Col1", "Col2")] <- df1[row_idx, c("Col2", "Col1")] } } print(df1)
内容的提问来源于stack exchange,提问作者Johan
相关产品推荐
相关产品推荐

