Open Archaeolithics opened 5 years ago
It is possible, albeit very hacky to workaround POSIXct's limitations. I came across a function as_BC_date
, from this repository. Then you need to split the AC and BC parts of your data frame and handle them separately. A user sent me a working example. I didn't workt through it, but a proper timeline with BC and AC dates is returned, so if you want to check that out:
library(vistime)
library(rcarbon)
library(lubridate)
# from https://rdrr.io/github/mvazquezs/romanddbb/src/R/00_romanddbb.stats.R
as_BC_date <- function(year, month = 1, day = 1){
if(year < 0) year<-(-year)
Y <- as.character(year)
M <- as.character(month)
D <- as.character(day)
fwdY <- paste(Y, "1", "1", sep = "/")
fwdYMD <- paste(Y, M, D, sep = "/")
AD0 <- lubridate::as_date("0000/1/1") ##merry xmas!
n_AD0 <- as.numeric(AD0)
n_fwdY <- as.numeric(lubridate::as_date(fwdY))
n_MD <- as.numeric(lubridate::as_date(fwdYMD)) -
as.numeric(lubridate::as_date(fwdY))
n_BC <- n_AD0 - (n_fwdY - n_AD0) + n_MD
if(n_MD==0) n_BC <- n_BC + 1
BC_date <- lubridate::as_date(n_BC)
return(BC_date)
}
data <- read.csv(text = "event, group, start, end, color, fontcolor
Period 1, Anthropo-Environmental Period, 6000, 3000, #676767, White
Period 2, Anthropo-Environmental Period, 3000, 800, #a6a6a6, White
First TOC, Groundwater (Carbon), 6000, 6000, #3973ac, Black
Peak TOC, Groundwater (Carbon), 1600, 1600, #6699cc, Black")
data[3]<-as.data.frame(BPtoBCAD(as.vector(t(data[3])))) #uses function from rcarbon to convert from BP to BCE/AD
data[4]<-as.data.frame(BPtoBCAD(as.vector(t(data[4]))))
data_AD<-data #have to split the dataframe into two sections and treat BCE separately from AD
data[3][data[3]>0] <- NA #Anything AD is set to NA
data[4][data[4]>0] <- NA
data_AD[3][data_AD[3]<0] <- NA #Anything BCE is set to NA
data_AD[4][data_AD[4]<0] <- NA
data[3]<-as.data.frame(as_BC_date(as.numeric(t(data[3])))) #converts numbers to date (BCE)
data_AD[3]<-as.data.frame(as.Date(ISOdate(t(data_AD[3]),1,1))) #converts numbers to date (AD)
data_AD[4]<-as.data.frame(as.Date(ISOdate(t(data_AD[4]),1,1)))
data$start[is.na(data$start)] <- data_AD$start[match(data$event,data_AD$event)][which(is.na(data$start))] #recombine datasets
data$end[is.na(data$end)] <- data_AD$end[match(data$event,data_AD$event)][which(is.na(data$end))]
rm(data_AD) #remove surplus dataset
data <- as.data.frame(unclass(data)) #reformat
vistime(data) #visualise
The above solution only work if time is before 1000BC, it doesn't work for date such as 200BC.
` as_BC_date <- function(year, month = 1, day = 1){ if(year < 0) year<-(-year) Y <- as.character(str_pad(year,4, pad = "0")) ##I modified here M <- as.character(month) D <- as.character(day) fwdY <- paste(Y, "1", "1", sep = "/") fwdYMD <- paste(Y, M, D, sep = "/") AD0 <- lubridate::as_date("0000/1/1") ##merry xmas! n_AD0 <- as.numeric(AD0) n_fwdY <- as.numeric(lubridate::as_date(fwdY)) n_MD <- as.numeric(lubridate::as_date(fwdYMD)) - as.numeric(lubridate::as_date(fwdY)) n_BC <- n_AD0 - (n_fwdY - n_AD0) + n_MD if(n_MD==0) n_BC <- n_BC + 1 BC_date <- lubridate::as_date(n_BC)
return(BC_date)
}
BCDate.start1 <- as_BC_date(-320, 1, 1) BCDate.end1 <- as_BC_date(-20, 1, 1)
BCDate.start2 <- as_BC_date(-1320, 1, 1) BCDate.end2 <- as_BC_date(-1120, 1, 1)
timeline_data <- data.frame(event = c("Event 1", "Event 2"), start = c(BCDate.start1, BCDate.start2), end = c(BCDate.end1, BCDate.end2), group = "My Events")
vistime(timeline_data)`
you will see that only Event 2 is shown. Any work around?
The code above from April 12, 2020, showing that you can enter BC dates, does not actually work. First of all, the as_BC_date function won't take a vector of years (e.g., from a column in a data frame). It will only take one year at a time, so that part would need to be modified. Also, that function fails when an NA year is passed into it, so that needs modification. Those modifications are easy, however. The biggest problem is that at the end of it all, even with those fixes, that code makes it look like you can pass a dataframe into vistime that has been unclassed. The problem there is that if you unclass it, vistime can no longer find the start and end columns. If you rename (one of) the start column back to "start", the next problem you encounter is that 'end' needs an origin. If you supply an origin of, say, 1970-01-01, there are no more errors, and vistime is able to output something, but it is completely wrong. If you supply an origin of, say, 0000-01-01, then you see more things on the graph, but it too is completely wrong. So, if it sounds like a good idea, I would love to re-open the issue, since nothing I've tried is able to make it show anything like the graph above.
Also it appears the less-than-1000 BC (encompassing years in the first millennium BC, or 1 to 999) problem persists. ggplot2 is able to handle BC dates from 1 to 999, so hopefully this isn't too big of a fix.
Is there a possibility to enter BC (Before Christ) dates to create timelines only based on year-numbers? Particularly crossing the BC/AD border?