【问题标题】:as.Date function gives different result in a for loopas.Date 函数在 for 循环中给出不同的结果
【发布时间】:2017-03-30 21:56:47
【问题描述】:

当我将 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="")))

感谢您的宝贵时间!

【问题讨论】:

  • folders 中有什么内容?我认为可能有更好的方法来实现你想要的。你应该去掉origin参数中的as.Date()调用,as.Date函数会根据需要将参数转换为日期,或者如果具体,你也应该在这里给出一个来源。
  • @Tensibai 在文件夹中是一组在 1 天和 52 天采集的卫星图像。图像名称中是存储日期:LC81730382016267LGN00。这个例子是在 2016 年第 267 天捕获的。如下: as.Date(day, origin = as.Date(paste(year,jan, sep=""))) 将在 2016-09-24 转移它,即我想要的是。但它没有成功存储在 date_list 中
  • 我的意思是dput folders 会帮助你:)

标签: r loops output as.date


【解决方案1】:

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

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

as.Date 接受 format 参数,(%Y 和 %j 记录在 strptime 中),%j 是朱利安日,这比使用原点和多重粘贴更容易阅读来电。

您的问题实际上与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-01-01 以来的天数。当您使用 as.character 要求将日期作为字符表示形式时,它会给出正确的值,因为 Date 类作为 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 类,它一次性为我们提供 julian 日、年和日期。由于年份从 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" 

【讨论】:

  • 今天的英雄!谢谢!关于答案的第一部分的一个评论:在 for 循环中(遍历带有图像的文件夹)这仍然不起作用。在循环之外它确实如此。但是你的 lapply 功能很好用,谢谢。
  • @Jobbo90 确实,我一开始忽略了一部分,我编辑了答案以获得更完整的解释和正确的修复。
【解决方案2】:

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

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

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

这至少可能是问题的一部分。在这里提供一个示例来说明“场景”的典型值是什么。

【讨论】:

  • 儒略日的范围是 1 - 365,所以一天是三个数字。所以我不确定这怎么可能是问题的一部分。场景是文件夹中图像的名称,它是我使用的迭代器。喜欢:'LC81730382016267LGN00' 感谢您的宝贵时间!
  • 啊,在朱利安时代,我明白了,我的错!
猜你喜欢
  • 1970-01-01
  • 2016-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-01
相关资源
最近更新 更多