【问题标题】:How to import data in the right monthly order using list.files如何使用 list.files 以正确的月度顺序导入数据
【发布时间】:2012-03-28 17:53:48
【问题描述】:

我有 100 年的月度数据,其中每个月都是一个文件,文件名以数据的年份和月份结尾。

例如“cru_ts_3_10.1901.2009.pet_1901_1.asc”是 1901 年第 1 个月(1 月)的文件。

问题是当我列出我的文件时,文件的顺序发生了变化,月份 10、11 和 12 出现在 1 之后:

files <- list.files(pattern=".asc") 
head(files)

[1] "cru_ts_3_10.1901.2009.pet_1901_1.asc"  "cru_ts_3_10.1901.2009.pet_1901_10.asc" "cru_ts_3_10.1901.2009.pet_1901_11.asc"
[4] "cru_ts_3_10.1901.2009.pet_1901_12.asc" "cru_ts_3_10.1901.2009.pet_1901_2.asc"  "cru_ts_3_10.1901.2009.pet_1901_3.asc" 

我知道为什么会发生这种情况,但是如何按正确的月度顺序导入我的数据?

【问题讨论】:

  • 出于好奇,为什么需要以正确的顺序导入数据?这对我来说似乎很不寻常 - 在我能想到的所有情况下,一旦你将记录导入后,对它们进行排序会更容易......
  • @MattParker 如果数据文件很大,也许您一次只想加载几个文件,但您更愿意抓取 1 月和 2 月而不是 1 月和 10 月。跨度>

标签: r import


【解决方案1】:

另一个基于regex 的解决方案。它通过从文件名中提取年份和月份来构造一个真实的日期,然后使用排序顺序来打印文件列表。

pat <- "^.*pet_([0-9]{1,})_([0-9]{1,}).asc$"
ord_files <- as.Date(gsub(pat, sprintf("%s-%s-01", "\\1", "\\2"), files))
files[order(ord_files)]

解释

我们使用正则表达式来匹配文件名中的yearmonth。因此,\\1 匹配 year\\2 匹配月份。我们仍然需要将其转换为日期。语句sprintf("%s-%s-01",\1,\2)yearmonth 的值代替%s。将字符串转换为日期需要as.Date

【讨论】:

  • 您能解释一下sprintf("%s-%s-01", "\\1", "\\2") 的工作原理吗?
【解决方案2】:
files <- c("cru_ts_3_10.1901.2009.pet_1901_1.asc", 
           "cru_ts_3_10.1901.2009.pet_1901_10.asc", 
           "cru_ts_3_10.1901.2009.pet_1901_11.asc", 
           "cru_ts_3_10.1901.2009.pet_1901_12.asc", 
           "cru_ts_3_10.1901.2009.pet_1901_2.asc", 
           "cru_ts_3_10.1901.2009.pet_1901_3.asc",
           "cru_ts_3_10.1901.2009.pet_1902_1.asc",
           "cru_ts_3_10.1901.2009.pet_1902_10.asc", 
           "cru_ts_3_10.1901.2009.pet_1902_11.asc")

这会拆分下划线的名称,并选择最后一部分。 (例如“1.asc”)并使用sub 删除“.asc”。然后它将剩下的内容转换为一个数字,并在该数字上使用sprintf 来获得一个 2 个字符(数字)的字符串。然后它将年份和月份转换为一个数字,并以此为基础orders。

files[order(sapply(strsplit(files, "_"), function(x) {
    m <- sprintf("%02d", as.numeric(sub(".asc", "", last(x)))) # turns "1.asc" into "01"
    as.numeric(paste(x[length(x) - 1], m, sep=""))
}))]

返回:

[1] "cru_ts_3_10.1901.2009.pet_1901_1.asc" 
[2] "cru_ts_3_10.1901.2009.pet_1901_2.asc" 
[3] "cru_ts_3_10.1901.2009.pet_1901_3.asc" 
[4] "cru_ts_3_10.1901.2009.pet_1901_10.asc"
[5] "cru_ts_3_10.1901.2009.pet_1901_11.asc"
[6] "cru_ts_3_10.1901.2009.pet_1901_12.asc"
[7] "cru_ts_3_10.1901.2009.pet_1902_1.asc" 
[8] "cru_ts_3_10.1901.2009.pet_1902_10.asc"
[9] "cru_ts_3_10.1901.2009.pet_1902_11.asc"

【讨论】:

  • 谢谢,这解决了几个月的问题,但又造成了几年的问题,现在我把所有的一月都放在一起(一月的 100 年),然后是 100 年的二月.... > head(files2 ) [1] "cru_ts_3_10.1901.2009.pet_1901_1.asc" [2] "cru_ts_3_10.1901.2009.pet_1902_1.asc" [3] "cru_ts_3_10.1901.2009.pet_1903_1.asc" [4] "cru_ts_3_10.1901.2 5]“cru_ts_3_10.1901.2009.pet_1905_1.asc”[6]“cru_ts_3_10.1901.2009.pet_1906_1.asc”
  • 我收到一个错误:Error: unexpected '}' in: "+ as.numeric(paste(x[length(x) - 1], m, sep="")) + }"
  • 我从终端复制并粘贴了已经执行的内容。在粘贴之前,您必须删除“>”和“+”。我清理了它,所以你应该可以复制和粘贴
  • 感谢这也有效(+1,因为我只能接受 1 个答案)
【解决方案3】:

查看gtools 包中的mixedsort 函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-10
    • 2019-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-12
    • 1970-01-01
    • 2019-03-15
    相关资源
    最近更新 更多