我在R脚本中有以下要求(在Spotfire中编写表达式函数):
dateString <- "04/30/2015 03/21/2015 06/28/2015 12/19/2015"
startDate <- "04/01/2015"
endDate <- "07/01/2015"
注意:dateString可以包含任意数量的日期。
如果dateString中的所有日期都在startDate和endDate之间,则需要返回“Yes”/ TRUE,否则返回“No”/ FALSE。
答案 0 :(得分:6)
转换为&#39;日期&#39>后,您可以使用between
中的便捷功能dplyr/data.table
。类。 &#39; dateString&#39;是一个字符串,我们可以使用strsplit
或仅使用scan
在空白处拆分。
library(lubridate)
library(data.table)
between(mdy(scan(text=dateString, what='', quiet=TRUE)),
mdy(startDate), mdy(endDate))
上述单行可以拆分为不同的步骤,以便于理解。
#split the string to substring at whitespace.
v1 <- scan(text=dateString, what='', quiet=TRUE)
#convert to Date class
v2 <- mdy(v1)
#use between to get a logical index of the dates
#that are between 'startDate' and 'endDate'
res <- between(v2, mdy(startDate), mdy(endDate))
res
#[1] TRUE FALSE TRUE FALSE
为了完整起见,如果我们需要&#39;是/否&#39;代替&#39; TRUE / FALSE&#39;我们可以使用ifelse
。 ifelse
部分会更容易理解。如果元素为&#39; TRUE&#39;则会将其替换为&#39;是&#39;否则它将被&#39; No&#39;取代。
ifelse(res, 'Yes', 'No')
#[1] "Yes" "No" "Yes" "No"
或数字索引以替换&#39; res&#39;。
中的值 c('No', 'Yes')[res+1L]
#[1] "Yes" "No" "Yes" "No"
上述步骤可能有点令人困惑。但是,每当我发现不太明显的东西时,我就会将代码分成尽可能小的代码。在这里,我会寻找
res+1L
#[1] 2 1 2 1
添加/乘以逻辑索引将逻辑索引强制转换为二进制整数,即0/1。这里我们添加了1L
或整数1.会发生的是,强制为1的TRUE值将被添加1L以获得2而FALSE被强制为0将添加1和0+1 = 1
。
当逻辑索引转换为数字索引时,我们使用它来替换字符串c('No', 'Yes')
的向量。请注意,在字符串的第一个位置是“否”&#39;在第二个位置它是&#39;是&#39;。根据数字索引的长度,即&#39; 4&#39;以及该索引指定的位置索引,我们用&#39;是/否&#39;替换索引。
我们也可以不使用任何外部包。
v2 <- as.Date(v1, '%m/%d/%Y')
v2 >= as.Date(startDate, '%m/%d/%Y') & v2 <= as.Date(endDate, '%m/%d/%Y')
#[1] TRUE FALSE TRUE FALSE
如果我们不需要考虑“开始日期”&#39;和&#39; endDate&#39;,将>=/<=
替换为>/<
答案 1 :(得分:5)
这是一种没有额外包装的替代解决方案。
首先,将字符串表示为日期:
dates <- lapply(strsplit(dateString, " +")[[1L]], as.Date, "%m/%d/%Y")
start <- as.Date(startDate, "%m/%d/%Y")
end <- as.Date(endDate, "%m/%d/%Y")
其次,检查日期是否在开始和结束之间:
sapply(dates, function(x) x >= start && x <= end)
# [1] TRUE FALSE TRUE FALSE