I am working from an nc file and after extracting the data to a matrix the time variable is the column variable for this it just gave it a number 1:2087 for the range of time for the dataset. I would like to rename it to the date that they should be (starting at 1981/12/31 to 2021/12/31 where each column is a week) I tried to change the names by using
colnames(tmp_mat) <- rep(seq(as.Date('1982-01-05'), as.Date('2021-12-28'), by = 'weeks'))
this changed the column names but it changed it to a number (the number of days for that date since 1971/01/01.
Does anyone have any suggestions in how to make this work
Your data is a matrix , you have to change it to data.frame then apply your code
tmp_mat = data.frame(tmp_mat)
colnames(tmp_mat) <- rep(seq(as.Date('1982-01-05'), as.Date('2021-12-28'), by = 'weeks'))
Related
This question already has an answer here:
r - Filter a rows by a date that alters each day
(1 answer)
Closed 1 year ago.
I have a question about the use of a logical expression in combination with a variable.
Imagine that I have a data frame with multiple rows that each contain a date saved as 2021-09-25T06:04:35:689Z.
I also have a variable that contains the date of yesterday as '2021-09-24' - yesterday <- Sys.Date()-1.
How do I filter the rows in my data frame based on the date of yesterday which is stored in the variable 'yesterday'?
To solve my problem, I have looked at multiple posts, for example:
Using grep to help subset a data frame
I am well aware that this question might be a duplicate. However, current questions do not provide me with the help that I need help. I hope that one of you can help me.
As an initial matter, it looks like you have a vector instead of a data frame (only one column). If you really do have a data frame and only ran str() on one column, the very similar technique at the end will work for you.
The first thing to know is that your dates are stored as character strings, while your yesterday object is in the Date format. R will not let you compare objects of different types, so you need to convert at least one of the two objects.
I suggest converting both to the POSIXct format so that you do not lose any information in your dates column but can still compare it to yesterday. Make sure to set the timezone to the same as your system time (mine is "America/New_York").
Dates <- c("2021-09-09T06:04:35.689Z", "2021-09-09T06:04:35.690Z", "2021-09-09T06:04:35.260Z", "2021-09-24T06:04:35.260Z")
Dates <- gsub("T", " ", Dates)
Dates <- gsub("Z", "", Dates)
Dates <- as.POSIXct(Dates, '%Y-%m-%d %H:%M:%OS', tz = "America/New_York")
yesterday <- Sys.time()-86400 #the number of seconds in one day
Now you can tell R to ignore the time any only compare the dates.
trunc(Dates, units = c("days")) == trunc(yesterday, units = c("days"))]
The other part of your question was about filtering. The easiest way to filter is subsetting. You first ask R for the indices of the matching values in your vector (or column) by wrapping your comparison in the which() function.
Indices <- which(trunc(Dates, units = c("days")) == trunc(yesterday, units = c("days"))])
None of the dates in your str() results match yesterday, so I added one at the end that matches. Calling which() returns a 4 to tell you that the fourth item in your vector matches yesterday's date. If more dates matched, it would have more values. I saved the results in "Indices"
We can then use the Indices from which() to subset your vector or dataframe.
Filtered_Dates <- Dates[Indices]
Filtered_Dataframe <- df[Indices,] #note the comma, which indicates that we are filtering rows instead of columns.
I'm trying to create dataframe in R with a date column that is populated from a pre-defined variable. When I do this the date is changed to a seemingly random future date. Here is what I have:
DateVar <- as.Date("2/6/2020", format = "%m/%d/%Y")
Size <- 50
Results <- data.frame(COMP_NAM=character(Size),
COMM_DTE=as.Date(Size, origin = DateVar),
ID=character(Size),
stringsAsFactors=FALSE)
Then when I look at the dataframe, column COMM_DTE is populated with "2020-04-29". But when I print DateVar R returns "2020-02-06".
Does anyone know why this is happening and how to fix it? Thank you!
everyone!
As part of my clinical study I created a xlsx spreadsheet containing a data set. Only columns 2 to 12 and lines 1 to 307 are useful to me. I now manipulate my spreadsheet under R, after importing it (read_excel, etc.).
In my columns 11 and 12 ('data' and 'raw_data'), some cells correspond to dates (for example the first 2 rows of 'data' and 'raw_data'). Indeed, this corresponds to the patient's visit dates. However, as you can see, these dates are given to me in number of days since the origin "1899-12-30". However, I would like to be able to transform them into a current date format (2019-07-05).
My problem is that in these columns I don't only have dates, I have different numerical results (times, means, scores, etc.) .
I started by transforming the class of my columns from character to factor/numeric so that I could better manipulate the columns later. But I can't change only the format of cells corresponding to a date.
Do you know if it is possible to transform only the cells concerned and if so how?
I attach my code and a preview of my data frame.
Part "Unsuccessful trial": I tried with this kind of thing. Of course the date changes format here but as soon as I try to make this change in the data frame it doesn't work.
Thank you for your help!
# Indicate the id of the patient
id = "01_AA"
# Get protocol data of patient
idlst <- dir("/data/protocolData", full.names = T, pattern = id)
# Convert the xlsx database into dataframe
idData <- data.table::rbindlist(lapply(
idlst,
read_excel,
n_max = 307,
range = cell_cols("B:M"), # just keep the table
), fill = TRUE)
idData <- as.tibble(idData)
idData<- idData %>%
mutate_at(vars(1:10), as.factor)%>%
mutate_at(vars(11:length(idData)), as.numeric)
# Unsuccessful trial
as.Date.character(data[1:2,11:12], origin ='1899-12-30')
Thank you for your comments and indeed this is one of the problems with R.
I solved my problem with the following code where idData is my df.
# Change the data format of the date cells of the column Data and Raw_data:
idData$Data[grepl("date",idData$Measure)] <- as.character(as.Date(
as.numeric(
idData$Data[grepl("date",idData$Measure)]),
origin = "1899-12-30"))
I'm new to R (having worked in C++ and Python before) so this is probably just a factor of me not knowing some of R's nuances.
The program I'm working on is supposed to construct matrices of data by date. Here's how I might initialize such a matrix:
dates <- seq(as.Date("1980-01-01"), as.Date("2013-12-31"), by="days")
HN3 <- matrix(nrow=length(dates), ncol = 5, dimnames = list(as.character(dates), c("Value1", "Value2", "Value3", "Value4", "Value5")))
Notice that dates includes every day between 1980 and 2013.
So, from there, I have files containing certain dates and measurements of Value1, etc for those dates, and I need to read those files' contents into HN3. But the problem is that most of the files don't contain measurements for every day.
So what I want to do is read a file into a dataframe (say, v1read) with column 1 being dates and column 2 being the desired data. Then I'd match the dates of v1read to that date's row in HN3 and copy all of the relevant v1read values that way. Here is my attempt at doing so:
for (i in 1:nrow(v1read)) {
HN3[as.character(v1read[i,1]),Value1] <- v1read[i,4]
}
This gives me an out of index range error when the value of i is bumped up unexpectedly. I understand that R doesn't like to iterate through dates, but since the iterator itself is a numeric value rather than a date, I was hoping I'd found a loophole.
Any tips on how to accomplish this would be enormously appreciated.
Let's use library(dplyr). Start with
dates = seq(as.Date("1980-01-01"), as.Date("2013-12-31"), by="days")
HN3 = data.frame(Date=dates)
Now, load in your first file, the one that has a date and Value1.
file1 = read.file(value1.file) #I'm assuming this file has a column already named "Date" and one named #Value1
HN3 = left_join(HN3,file1,by="Date")
This will do a left join (SQL style) matching only the rows where a date exists and filling in the rest with NA. Now you have a data frame with two columns, Date and Value1. Load in your other files, do a left_join with each and you'll be done.
I have a data frame with a date column titled 'End_Date'. I want to add a new column 'Start_Date' that calculates the day after the previous 'End_Date'. For example:
End_Date <-as.Date(c("2010-11-01", "2010-11-18", "2010-11-26"))
dates <-data.frame(End_Date)
In this example, the new column 'Start Date' to look like this:
dates$Start_Date <-as.Date(c(NA, "2010-11-02", "2010-11-19"))
I have tried using sapply, but get an error stating that the new column has one too few rows:
dates$Start_Date <-sapply(2:nrow(dates),
function(i) (dates$End_Date[i]-dates$End_Date[i-1]))
Here, I created a data frame with only 3 rows just as an example, but I need to solution that I can apply to data frames with large numbers of rows.
Try:
dates$Start_Date<-rep(as.Date(NA,origin = "1970-01-01"),nrow(dates))
for(i in 2:nrow(dates)) {dates$Start_Date[i]<- as.Date(dates$End_Date[i-1]+1)}
Or as Richard suggested in the comments, a much better method is:
dates$Start_Date<-as.Date(c(NA, (End_Date+1)[-length(End_Date)]), origin = "1970-01-01")