CDISC datasets from R. Why not? [Software]
❝ While Phoenix needs an additional package to be purchased, I feel that the same can be done by creating tables on phoenix (or importing in .csv) and exporting it to .xpt without the specific package which I assume will only help with limited datasets.
I did that myself before I got Certara’s CDISC-license. Never tried anything else than raw-data (scheduled & actual time points, concentrations) and NCA-results.
❝ ❝ If you are an experienced R-coder, consider writing a package …
❝
❝ I might not be an expert coder/programmer, but I have been working on this for quite some time. Thank you for the references, will definitely try doing something.
Needs patience and the learning curve is not flat. A coding environment like R-Studio and an account at GitHub greatly helps.
❝ It really has been a challenge to get it validated using pinnacle validator.
I believe it. Congratulations!
❝ Also, when it comes to Adam datasets it specially requires SAS date format which I assume is not possible to be created on R.
SAS’ date value (days since 1960-01-01) and datetime (seconds since 1960-01-01 midnight) are a pain in the ass. The format
ddmmmyy:hh:mm:ss
is just ugly. I played around in R a bit and see what you mean. I wouldn’t say it’s impossible, only tricky.*The “origin” of date- and time-objects in R is (like the UNIX Epoch time) 1970-01-01 00:00:00 UTC. The timezone is important. Is National Language Support (NLS) part of SAS’ base installation? Without, everything is in local time. I found a funny document stating
The last counter is the datetime counter. This is the number of seconds since midnight, January 1, 1960. Why January 1, 1960? One story has it that the founders of SAS wanted to use the approximate birth date of the IBM 370 system, and they chose January 1, 1960 as an easy-to-remember approximation.
Heck, did they mean the timezone (EST = UTC-5) of Poughkeepsie, NY?The man-page of
as.POSIX()
claims that the origin of SAS’ datetime is 1960-01-01 00:00:00 GMT but I prefer to avoid a second-hand reference.❝ While No other regulatory mandates datasets for Bio equivalence study, I still keep wondering what really sparked the USFDA in the mid of Dec 2016 to make CDISC datasets mandate for regulatory submission.
Not the slightest idea.
# Note: Dates without times are treated as being at midnight UTC.
timestamps <- c('1959-12-31 23:59:59', '1960-01-01 00:00:00', '1960-01-01 00:00:01',
'1960-01-01 00:59:59', '1960-01-01 01:00:00', '1960-01-01 01:00:01',
'1970-01-01 00:59:59', '1970-01-01 01:00:00', '1970-01-01 01:00:01',
'2019-03-21 00:00:00', '2019-03-21 12:00:00', '2019-03-21 15:00:00')
# Use time objects (class 'POSIXct') and not date objects (class 'POSIXlt')
# Otherwise, we cannot deal with timezones later.
POSIXtimes <- as.POSIXct(strptime(timestamps, format='%Y-%m-%d %H:%M:%S'))
POSIXtimes <- c(POSIXtimes, Sys.time()) # Add current timestamp for fun.
print(POSIXtimes) # Show what we have.
# In the /local/ timezone but the origin of POSIX is '1970-01-01 00:00:00 UTC'.
# The /internal/ presentation of class 'POSIXct' is secs since the origin.
POSIXtimes.UTC <- POSIXtimes
# Convert the timezone (shift from local time to UTC)
attr(POSIXtimes.UTC, 'tzone') <-'UTC'
print(POSIXtimes.UTC) # Bingo!
POSIX.secs <- as.integer(POSIXtimes.UTC) # Seconds since origin.
POSIX.origin <- 0
SAS.origin <- as.integer(as.POSIXct(strptime('1960-01-01 00:00:00',
format='%Y-%m-%d %H:%M:%S',
tz='UTC')))
SAS.secs <- POSIX.secs - SAS.origin
# SAS DATETIME Format without fractional seconds: ddmmmyy:hh:mm:ss
# We have to make sure that the locale is set to English to get correct
# abbrevations of three-character months!
lct <- Sys.getlocale("LC_TIME")
invisible(Sys.setlocale("LC_TIME", "C"))
SAS.datetime <- format(POSIXtimes.UTC, format='%d%b%y:%H:%M:%S')
res <- data.frame(POSIX.local=POSIXtimes, POSIX.UTC=POSIXtimes.UTC,
POSIX.secs, SAS.secs, SAS.datetime,
stringsAsFactors=FALSE)
print(res, row.names=FALSE)
invisible(Sys.setlocale("LC_TIME", lct)) # restore original settings
Gave on my machine (timezone CET=UTC+1):
POSIX.local POSIX.UTC POSIX.secs SAS.secs SAS.datetime
1959-12-31 23:59:59 1959-12-31 22:59:59 -315622801 -3601 31Dec59:22:59:59
1960-01-01 00:00:00 1959-12-31 23:00:00 -315622800 -3600 31Dec59:23:00:00
1960-01-01 00:00:01 1959-12-31 23:00:01 -315622799 -3599 31Dec59:23:00:01
1960-01-01 00:59:59 1959-12-31 23:59:59 -315619201 -1 31Dec59:23:59:59
1960-01-01 01:00:00 1960-01-01 00:00:00 -315619200 0 01Jan60:00:00:00
1960-01-01 01:00:01 1960-01-01 00:00:01 -315619199 1 01Jan60:00:00:01
1970-01-01 00:59:59 1969-12-31 23:59:59 -1 315619199 31Dec69:23:59:59
1970-01-01 01:00:00 1970-01-01 00:00:00 0 315619200 01Jan70:00:00:00
1970-01-01 01:00:01 1970-01-01 00:00:01 1 315619201 01Jan70:00:00:01
2019-03-21 00:00:00 2019-03-20 23:00:00 1553122800 1868742000 20Mar19:23:00:00
2019-03-21 12:00:00 2019-03-21 11:00:00 1553166000 1868785200 21Mar19:11:00:00
2019-03-21 15:00:00 2019-03-21 14:00:00 1553176800 1868796000 21Mar19:14:00:00
2019-03-21 16:03:24 2019-03-21 15:03:24 1553180604 1868799804 21Mar19:15:03:24
To get SAS’ date simply truncate the string withsubstr(SAS.datetime, 1, 7)
.
TODO: Convert(done)SAS.secs
andSAS.datetime
(in UTC) back to the local date/time.
Dif-tor heh smusma 🖖🏼 Довге життя Україна!
Helmut Schütz
The quality of responses received is directly proportional to the quality of the question asked. 🚮
Science Quotes
Complete thread:
- CDISC datasets or R. Acceptable ?? WhiteCoatWriter 2019-03-21 07:13 [Software]
- CDISC datasets from R. Why not? Helmut 2019-03-21 10:47
- CDISC datasets from R. Why not? WhiteCoatWriter 2019-03-21 12:13
- CDISC datasets from R. Why not?Helmut 2019-03-21 16:43
- CDISC datasets from R. Why not? WhiteCoatWriter 2019-03-22 06:56
- Some code Helmut 2019-03-22 16:58
- Some code WhiteCoatWriter 2019-03-24 07:59
- SAS only? Helmut 2019-03-24 12:34
- SAS only? WhiteCoatWriter 2019-03-25 09:39
- Confusing… Helmut 2019-03-25 13:44
- Confusing… WhiteCoatWriter 2019-03-27 06:55
- Confusing… Helmut 2019-03-25 13:44
- SAS only? WhiteCoatWriter 2019-03-25 09:39
- SAS only? Helmut 2019-03-24 12:34
- Some code WhiteCoatWriter 2019-03-24 07:59
- Some code Helmut 2019-03-22 16:58
- CDISC datasets from R. Why not? WhiteCoatWriter 2019-03-22 06:56
- CDISC datasets from R. Why not?Helmut 2019-03-21 16:43
- CDISC datasets from R. Why not? WhiteCoatWriter 2019-03-21 12:13
- CDISC datasets from R. Why not? Helmut 2019-03-21 10:47