Check if date is between two dates in another data frame, and manipulate date if it is
With data.table
this is relatively simple with a non-equi update join:
library(data.table)
setDT(df1)
setDT(df2)
df1[df2
, on = .(ID
, unique_posix > Date.Time.Start
, unique_posix < Date.Time.End)
, `:=`(Dive.Shape = Shape, Dive.Depth = Depth)]
df1
> df1
ID unique_posix Dive.Shape Dive.Depth
1: SW12 2010-05-03 16:47:00 <NA> NA
2: SW12 2010-05-03 16:53:00 <NA> NA
3: SW12 2010-05-03 17:00:00 V 3
4: SW12 2010-05-03 18:00:00 Square 4
5: SW12 2010-05-03 18:12:00 <NA> NA
6: SW13 2010-08-15 17:13:00 U 6
7: SW13 2010-08-15 17:18:00 U 6
8: SW13 2010-08-15 17:37:00 U 7
9: SW13 2010-08-15 18:00:00 Square 8
10: SW13 2010-08-15 18:52:00 <NA> NA
See also: How to do a data.table rolling join?
If date between two dates in second table return value
You can try the following:
library(tidyverse)
library(lubridate)
dates <- dates %>%
mutate(match_date = format(date, "%Y-%m-%d"),
match_hour = hour(date - minutes(1)))
lookup <- lookup %>%
mutate(match_date = format(begin, "%Y-%m-%d"),
match_hour = hour(begin))
left_join(dates, lookup, by = c("match_date", "match_hour")) %>%
filter(date >= begin & date <= end) %>%
select(- match_date, - match_hour) %>%
head()
# A tibble: 6 x 5
# date begin end value1 value2
# <dttm> <dttm> <dttm> <int> <int>
# 1 2017-07-01 00:15:00 2017-07-01 00:01:00 2017-07-01 01:00:00 1 2
# 2 2017-07-01 00:30:00 2017-07-01 00:01:00 2017-07-01 01:00:00 1 2
# 3 2017-07-01 00:45:00 2017-07-01 00:01:00 2017-07-01 01:00:00 1 2
# 4 2017-07-01 01:00:00 2017-07-01 00:01:00 2017-07-01 01:00:00 1 2
# 5 2017-07-01 01:15:00 2017-07-01 01:01:00 2017-07-01 02:00:00 3 4
# 6 2017-07-01 01:30:00 2017-07-01 01:01:00 2017-07-01 02:00:00 3 4
First I extract the dates and hour of the day to match on. I substract one minute from the date in the dates
-table as your end times in your lookup
-table contain the times sharp (I mean e.g. 01:00:00). As I want to join on the begin-dates to get the right matching hour (e.g. 0 in this case), I substract the minute.
Then I do a left_join
of dates
and lookup
and filter
on your desired criteria.
Check if a date is within an interval in R
Everybody has their favourite tool for this, mine happens to be data.table because of what it refers to as its dt[i, j, by]
logic.
library(data.table)
dt <- data.table(date = as.IDate(pt))
dt[, YR := 0.0 ] # I am using a numeric for year here...
dt[ date >= as.IDate("2002-09-01") & date <= as.IDate("2003-08-31"), YR := 1 ]
dt[ date >= as.IDate("2003-09-01") & date <= as.IDate("2004-08-31"), YR := 2 ]
dt[ date >= as.IDate("2004-09-01") & date <= as.IDate("2005-08-31"), YR := 3 ]
I create a data.table
object, converting your times to date for later comparison. I then set up a new column, defaulting to one.
We then execute three conditional statements: for each of the three intervals (which I just create by hand using the endpoints), we set the YR
value to 1, 2 or 3.
This does have the desired effect as we can see from
R> print(dt, topn=5, nrows=10)
date YR
1: 2003-06-11 1
2: 2004-08-11 2
3: 2004-06-03 2
4: 2004-01-20 2
5: 2005-02-25 3
---
96: 2002-08-07 0
97: 2004-02-04 2
98: 2006-04-10 0
99: 2005-03-21 3
100: 2003-12-01 2
R> table(dt[, YR])
0 1 2 3
26 31 31 12
R>
One could have done this also simply by computing date differences and truncating down, but it is also nice to be a little explicit at times.
Edit: A more generic form just uses arithmetic on the dates:
R> dt[, YR2 := trunc(as.numeric(difftime(as.Date(date),
+ as.Date("2001-09-01"),
+ unit="days"))/365.25)]
R> table(dt[, YR2])
0 1 2 3 4 5 6 7 9
7 31 31 12 9 5 1 2 1
R>
This does the job in one line.
count row if date falls within date range for all dates in series in R
Here's a base R method:
date = seq(min(df$start_date), max(df$end_date))
count = sapply(date, \(x) sum(x >= df$start_date & x <= df$end_date))
data.frame(date, count)
# date count
# 1 1 2
# 2 2 4
# 3 3 5
# 4 4 6
# 5 5 7
# 6 6 6
# 7 7 5
# 8 8 4
# 9 9 3
# 10 10 2
# 11 11 1
Related Topics
Lme4::Lmer Reports "Fixed-Effect Model Matrix Is Rank Deficient", Do I Need a Fix and How To
Reading Multiple CSV Files from a Folder into a Single Dataframe in R
Stop an R Program Without Error
Connect to Postgres via Ssl Using R
How Does Cut with Breaks Work in R
How to Separate Comma Separated Values in R in a New Row
Best Way to Transpose Data.Table
Importing CSV File into R - Numeric Values Read as Characters
Ggplot2 - Adding Secondary Y-Axis on Top of a Plot
Plot a Function with Ggplot, Equivalent of Curve()
Case-Insensitive Search of a List in R
How to Add a Factor Column to Dataframe Based on a Conditional Statement from Another Column
Rscript: There Is No Package Called ...
How to Filter Rows Based on Difference in Dates Between Rows in R
Insert a Blank Row After Each Group of Data
Inputting Na Where There Are Missing Values When Scraping with Rvest