R语言:时间变量与日期的条件操作技术问询
Hey there! Let's work through this problem together. The core challenge here is converting that character-type HMS variable into a format we can actually compare against a cutoff time, then applying your date-shift logic. I'll show you two reliable approaches—one using the popular lubridate package (super user-friendly for time tasks) and another with chron since you mentioned you've looked into that.
Prerequisites
First, make sure your TimeStamp column is a proper Date type (not character). If it's not, convert it first with:
df$TimeStamp <- as.Date(df$TimeStamp)
Approach 1: Using lubridate (My Go-To)
lubridate simplifies parsing time strings and doing comparisons. Here's how to implement your logic:
# Load the package library(lubridate) # Step 1: Convert character HMS to seconds since midnight (easy to compare numerically) df$HMS_seconds <- hms(df$HMS) %>% period_to_seconds() # Step 2: Define our cutoff time (17:30:00) in total seconds cutoff_1730 <- 17 * 3600 + 30 * 60 # Equals 63000 seconds # Step 3: Create TimeStampNew with clear conditional logic df$TimeStampNew <- case_when( is.na(df$HMS) ~ df$TimeStamp, # Keep original date if HMS is missing df$HMS_seconds > cutoff_1730 ~ df$TimeStamp + days(1), # Shift to next day if after 17:30 TRUE ~ df$TimeStamp # Keep original date for all other cases )
Approach 2: Using chron (As You Explored)
If you prefer sticking with chron, we can convert the character HMS to a times object, which supports direct time comparisons:
# Load the package library(chron) # Step 1: Convert character HMS to chron's times object df$HMS_chron <- times(df$HMS) # Step 2: Define our cutoff time as a chron times object cutoff_time <- times("17:30:00") # Step 3: Create TimeStampNew with nested ifelse() df$TimeStampNew <- ifelse( is.na(df$HMS), df$TimeStamp, ifelse(df$HMS_chron > cutoff_time, df$TimeStamp + 1, df$TimeStamp) )
Quick Notes
- If your
HMSstrings have inconsistent formatting (e.g., missing leading zeros like"7:30:0"instead of"07:30:00"),lubridate::hms()usually handles this automatically. Forchron, you might need to clean the strings first (usestringr::str_pad()to add leading zeros where needed). - Double-check that
TimeStampis aDatetype—if it's a POSIXct datetime, addingdays(1)(lubridate) or+1(base R) will still work, and the core logic stays identical.
内容的提问来源于stack exchange,提问作者Chellarioo

