as.Date 函数在 for 循环中给出不同的结果

as.Date function gives different result in a for loop

当我将 as.Date 函数放入 for 循环时,它会给出不同的结果,这是一个小问题。我正在查看一个包含图像的子文件夹(按日期)的文件夹。我构建 date_list 来组织所有日期(用于稍后阶段的绘图选项)。儒略日从每年的一月一日开始,所以因为我有 4 年的日期,所以年份必须灵活。

# Set up list with 4 columns and counter Q. jan is used to set all dates to the first of january
date_list <- outer(1:52, 1:4)
q = 1
jan <- "-01-01"

for (scene in folders){
  year <- as.numeric(substr(scene, start=10, stop=13))
  day <- as.numeric(substr(scene, start=14, stop=16))
  datum <- paste(year, day, sep='_')
  date_list[q, 1] <- datum
  date_list[q, 2] <- year
  date_list[q, 3] <- day
  date_list[q, 4] <- as.Date(day, origin = as.Date(paste(year,jan, sep=""))) 
  q = q+1
}

输出最后一行:

[52,] "2016_267" "2016" "267" "17068"

我在 date_list[q, 4] 中缺少什么没有将我的整数转换为日期? 运行 以下代码确实有效,但由于场景和文件夹数量众多,我喜欢将其自动化:

 as.Date(day, origin = as.Date(paste(year,jan, sep="")))

感谢您的宝贵时间!

您的意思是将您的日期输出为 3 个数字吗?不应该是2个数吗?

day <- as.numeric(substr(scene, start=15, stop=16))

day <- as.numeric(substr(scene, start=14, stop=15))

这至少是问题的一部分。在这里提供 "scene" 的典型值的示例会有所帮助。

嗯,我想这会回答你的第一个问题:

date_list[q, 4] <- as.character(as.Date(datum,format="%Y_%j"))

as.Date接受一个format参数,(%Y和%j在strptime中有记载),%j是儒略日,这是一个比使用 origin 和多个粘贴调用更容易阅读。

您的问题实际上与 Date 对象是什么有关:

> dput(as.Date("2016-01-10"))
structure(16810, class = "Date")

当输入 matrix(您的 date_list)时,它被强制转换为字符 w 像这样之前没有特殊处理:

> d<-as.Date("2016-01-10")
> class(d)<-"character"
> d
[1] "16810"

因此您只能得到自 1970 年 1 月 1 日以来的天数。当您使用 as.character 要求日期作为字符表示时,它会给出正确的值,因为 Date class 作为 as.character 方法首先以人类格式计算日期返回一个字符值。


现在,如果我能很好地理解你的问题,我会这样做:

首先创建一个函数来处理一个字符串:

name_to_list <- function(name) {
  dpart <- substr(name, start=10, stop=16)
  date <- as.POSIXlt(dpart, format="%Y%j")
  c("datum"=paste(date$year+1900,date$yday,sep="_"), "year"=date$year+1900, "julian_day"=date$yday, "date"=as.character(date) )
}

此函数只获取您的子字符串,然后将其转换为 POSIXlt class,一次传递给我们儒略日、年份和日期。由于自 1900 年以来年份存储为整数(可能为负数),因此在字段中存储年份时我们必须添加 1900。

那么如果你的 folders 变量是一个字符串向量:

lapply(folders,name_to_list)

至于 folders=c("LC81730382016267LGN00","LC81730382016287LGN00","LC81730382016167LGN00") 给出:

[[1]]
       datum         year   julian_day         date 
  "2016_266"       "2016"        "266" "2016-09-23" 

[[2]]
       datum         year   julian_day         date 
  "2016_286"       "2016"        "286" "2016-10-13" 

[[3]]
       datum         year   julian_day         date 
  "2016_166"       "2016"        "166" "2016-06-15"