首先描述一下这次遇到的问题:
EXCEL中的日期显示格式为“年月日时分秒”,但直接使用openxlsx包中的read.xlsx函数读入时,该格式会自动转为数值,如:
在excel中:
在R中:
此时数据不能用于计算时间差和日期差等,因此要转为正常的日期格式方可进行计算。
解决方案有两种:
方案1:
加载readxl包,使用其中的read_excel()函数,可直接将日期型数据按照excel中的日期显示,而不会扭转为数值。结果如图:
此时可直接进行时差的计算:
diftim1 <- difftime(d$考试结束时间,d$考试开始时间)
方案2:
当读入后,显示为数值时,需要通过函数扭转为正常日期格式
as.POSIXlt.numeric(as.numeric(data_raw$考试结束时间)*24*60*60, tz = "UTC", origin = "1899-12-30")
由于不同系统的origin不同,因此需要根据原数据所在软件进行调整。
不同软件对应的origin:
## date given as number of days since 1900-01-01 (a date in 1989)as.Date(32768, origin = "1900-01-01")## Excel is said to use 1900-01-01 as day 1 (Windows default) or## 1904-01-01 as day 0 (Mac default), but this is complicated by Excel## incorrectly treating 1900 as a leap year.## So for dates (post-1901) from Windows Excelas.Date(35981, origin = "1899-12-30") # 1998-07-05## and Mac Excelas.Date(34519, origin = "1904-01-01") # 1998-07-05## (these values come from http://support.microsoft.com/kb/214330)## Experiment shows that Matlab's origin is 719529 days before ours,## (it takes the non-existent 0000-01-01 as day 1)## so Matlab day 734373 can be imported asas.Date(734373, origin = "1970-01-01") - 719529 # 2010-08-23## (value from## http://www.mathworks.de/de/help/matlab/matlab_prog/represent-date-and-times-in-MATLAB.html)
由于我们的数据是windows系统下的excel文件,因此应设置origin为1899-12-30。
时区也会对转换的日期造成一定的影响:
R中的时区
> Sys.timezone()[1] "Asia/Taipei"
通过验证excel的时间和R中时区转换的结果,得知excel中的数值要通过UTC时区进行转换,即:
as.POSIXlt.numeric(as.numeric(data_raw$考试结束时间)*24*60*60, tz = 'UTC', origin = "1899-12-30")
tz要指定为UTC,若数值转换涉及其他时区,则需进行一定的数值转换,如:
as.POSIXlt.numeric(as.numeric(data_raw$考试结束时间)*24*60*60-8*60*60, tz = "Asia/Taipei", origin = "1899-12-30")
因为"Asia/Taipei"时区与UTC差8个小时,所以要减去对应数值才能一致。
转换过后就可以进行时差的计算了。
综上,在R中的计算如果涉及日期时,要注意核对日期转换结果。
另外有一个今天解决的,分段计算数值区间的百分比问题,贴个代码:
theta <- matrix(c(1,2,3,4,5,6,7),7,1)score.level <- table(cut(theta,breaks=c(1,3,5,7),include.lowest=TRUE))/7
还……有一个今天解决的,
如果which到的内容为integer(0),这样是无法在数据框中进行索引的,比如有时我们需要将符合which条件的数据过滤掉,那么没有一个符合条件的时候就不能直接在数据框中负掉,如data[-which(),],如果直接这么做会得到一个空表。解决方法如下:
n <- which(diftim < 20)if(length(n)==0) data <- data else data <- data[-n,]