time split to constant daily intervals and summarise the results - r

I have a data frame contains time variable of object POSIXct in the following format: yyyy-mm-dd HH:MM:SS.
I've been able to split it into time intervals using: split(dfrm, cut((dfrm$time), "30 mins"))
However, this method starts the splitting from the minimum time value I have in my data; but, I'm interested in splitting the data to daily time intervals, and summarise the results whitin each time interval.
Here is some reproducible example (sorry for the "poor" example; I can't copy and paste right now):
dfrm <- data.frame(time=as.POSIXct(c("2017-02-01 00:58:53", "2017-02-01 00:53:02","2017-02-01 01:15:09","2017-02-01 02:28:08","2017-02-01 02:15:20","2017-02-01 02:37:25")))
So, using my splitting method mentioned above, I'll get 4 groups starts at 00:53:00 with intervals of 30 minutes (and the data will be splitted between 3 of that 4 groups with 3,1 and 2 observations). While I'm looking for something like that:
Interval Total rows
1 0
2 2
3 1
4 0
5 2
6 1
7 0
8 0
.
.
where 1 is for 00:00:00-00:30:00, 2 is for 00:30:00-01:00:00,..., 48 is for 23:30:00-00:00:00

Related

Creating time-varying covariates when time is different for each observation

I'm attempting to conduct survival analysis with time-varying covariates. The data comes from a longitudinal survey that is administered biannually, and currently looks something like this:
id event1yr event2yr income 14 income16 income18 income20
1 2014 2020 8 10 13 8
2 2018 NA 13 15 24 35
In the case of my study, I am trying to begin time (t_0) at event1yr, and measure time from that variable, which obviously is different for each observation. So, for instance, time to event for observation 1 is 6 years, whereas the time to event for observation 2 is right-censored and 2 years. The main issue comes with also trying to pull data from different time points since the beginning time is different. For instance, income for years 0-2 (exclusive) for observation 1 would come from income14, but income for year 0-2 for observation would come from income18. In the end, I'd like my data to look something like this:
id st.time end.time event2 censor inc
1 0 2 0 0 8
1 2 4 0 0 10
1 4 6 1 0 13
2 0 2 0 1 24
Thus, I'm trying to think of the best way to code to account for pulling the data from different points in time since the beginning reference time is not constant across observations.

Match() function only runs for 0, but not for other values

I use Time Series data (imported with read.csv()) and want to match() values from an other data frame (also imported with read.csv) to those recorded in my Time Series.
It looks like this:
df1 <- data.frame(hue=rawdata[,"hue"])
# This is my Time Series-raw data
hue
2017-07-01 00:00:00 0
2017-07-01 00:01:00 0
2017-07-01 00:02:00 0
2017-07-01 00:03:00 0
2017-07-01 00:04:00 0
2017-07-01 00:05:00 0
The Values change between 0 and 7 sometimes. Here's just a head() print
And this is the data frame I want to check it with:
df2 <- data.frame(hue=sz$hue, Q=sz$Q)
# sz is the imported csv file
hue Q
1 0 0
2 1 13
3 2 26
4 3 39
5 4 52
6 5 65
Here, the same: Just a head() print.
Now, my aim is to create a new column next to hue in my rawdata.
in this new column I want the Q-values depending on their hue of df2. For example: From minute Zero to five on 2017-07-01 the Q-value in the new column will be 0, because hue is 0.
I tried many things with the match function like:
df1$match=sz$Q[match(df1$hue, sz$hue)]
But it's only working for the 0's and not for other values like 1,2,3 etc. R only gives me NAs at those points.
It works perfectly in this Video:
Using Match function in R
Actually I'm not quite sure if this is really a "match"-problem or a more format problem because I checked these two things:
> df1["2017-07-21 23:20:00","hue"]==2 # the value at this date is actually 2!
[1] FALSE
> is.numeric(df1["2017-07-21 23:20:00","hue"])
[1] TRUE
Does anyone know what I can do to get R to consider all values?
Thank you so much for taking time for this!

How can I fill in NA values based on the next real value but divide that value between the preceding NAs?

Please note: this is a hyper simplified explanation of where the 'data' comes from, but where the data is from is irrelevant to the coding question.
I have a data set created by collecting water in a tube everyday.
I can't go and measure the tube every day (but the tube keeps filling) so there are gaps in the water value records.
This dummy data set shows where this has happened on days 5 and 10, because this is a dummy dataset I have made an assumption that each day 500ml of water goes into the tube (the real data set is a alot messier!)
dummy data
day<-c(1,2,3,4,5,6,7,8,9,10,11,12)
value<-c(500,500,500,500,NA,1000,NA,NA,NA,2000,500,500)
df<-data.frame(day,value)
Data explanation: I have collected every day for days 1:4 so the value for each day is 500ml, missed day 5 so the value is NA, collected on day 6 so the value is 1000ml (the water from day 5 and day 6 combined), missed 7,8,9, so values equal NA, collected on day 10 to give a value of 2000ml for the 4 days) then collected every day for the last two)
I would like to fill in the NA gaps by taking the value of the next 'real' measurement and dividing that value between the NA's and that value's day.Yes, I am assuming that if I have not made a measurement there is a constant process and that I can divide the last measurement equally between the days.
this is what the output data should look like
day<-c(1,2,3,4,5,6,7,8,9,10,11,12)
corrected.value<-c(500,500,500,500,500,500,500,500,500,500,500,500)
corrected.df<-data.frame(day,corrected.value)
Again this is just a dummy data set otherwise the easiest way would just be replace NA with 500 with 'value[is.na(value)] <- 500', but in the real data set the values can be 457.6, 779, 376, etc.
Also tried to do a loop but keep getting stuck...
Any ideas on how I can do this?
Help is greatly appreciated
Here's a possible solution :
# Create test Data:
# note that this is slightly different from your input
# but in this way you can better verify that it works as expected
day<-c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15)
value<-c(NA,500,500,500,NA,3000,NA,NA,NA,5000,500,500,NA,NA,NA)
df<-data.frame(day,value)
# "Cleansing" starts here :
RLE <- rle(is.na(df$value))
# we cannot do anything if last values are NAs, we'll just keep them in the data.frame
if(tail(RLE$values,1)){
RLE$lengths <- head(RLE$lengths,-1)
RLE$values <- head(RLE$values,-1)
}
afterNA <- cumsum(RLE$lengths)[RLE$values] + 1
firstNA <- (cumsum(RLE$lengths)- RLE$lengths + 1)[RLE$values]
occurences <- afterNA - firstNA + 1
replacements <- df$value[afterNA] / occurences
df$value[unlist(Map(f=seq.int,firstNA,afterNA))] <- rep.int(replacements,occurences)
Result :
> df
day value
1 1 250
2 2 250
3 3 500
4 4 500
5 5 1500
6 6 1500
7 7 1250
8 8 1250
9 9 1250
10 10 1250
11 11 500
12 12 500
13 13 NA
14 14 NA
15 15 NA

Getting a difference between time(n+1)-time(n) in a dataframe in r

I have a dataframe where the columns represent monthly data and the rows different simulations. the data I am working with accumulates over time so I want to take the difference between the months to get the true value for that month. There are not headers for my data frame
For example:
View(df)=
1 3 4 6 19 23 24 25 26 ...
1 2 3 4 5 6 7 8 9 ...
0 0 2 3 5 7 14 14 14 ...
My plan was to use the diff() function or something like it, but I am having trouble using it on a dataframe.
I have tried:
df1<-diff(df, lag = 1, differences = 1)
but only get zeros.
I am grateful for any advice.
see ?apply. If it's a data frame
apply(df,2,diff)
should work. Also since a dataframe is a list of vectors sapply(df,diff) should work.

drawing multiple boxplots from imputed data in R

I have an imputed dataset that I'm analysing, and I'm trying to draw boxplots, but I can't wrap my head around the proper procedure.
my data (a sample, original has 20 observations per imputation and 13 vars per group, all values range from 0 to 25):
.imp .id FTE_RM FTE_PD OMZ_RM OMZ_PD
1 1 25 25 24 24
1 2 4 0 2 6
1 3 11 5 3 2
1 4 12 3 3 3
2 1 20 15 15 15
2 2 4 1 2 3
2 3 0 0 0 6
2 4 20 0 0 0
.imp signifies the imputation round, .id the identifer for each observartion.
I want to draw all the FTE_* variables in a single plot (and the `OMZ_* in another), but wonder what to do with all the imputations, can I just include all values? The imputated data now has 500 observations. With for instance an ANOVA I'd need to average the ANOVA results by 5 to get back to 20 observations. But is this needed for a boxplot as well, since I only deal with medians, means, max. and min.?
Such as:
data_melt <- melt(df[grep("^FTE_", colnames(df))])
ggplot(data_melt, aes(x=variable, y=value))+geom_boxplot()
I've played a couple of times with ggplot, but consider myself a complete newbie.
I assume you want to keep the identifier for .imp and .id after melting so rather put:
data_melt <- melt(df,c(".imp",".id"))
For completeness of the dataframe it probably helps to introduce a column that identifies the type - FTE vs. OMZ:
data_melt$type <- ifelse(grepl("FTE",data_melt$variable),"FTE","OMZ")
Having this data.frame you can, for example, facet on the type (alternatively you can just use a simple filter statement on data_melt to restrict to one type):
ggplot(data_melt, aes(x=variable, y=value))+geom_boxplot()+facet_wrap(~type,scales="free_x")
This would look like this.
EDIT: fixed the data mess-up

Resources