【问题标题】:sort character vector by multiple numbers按多个数字对字符向量进行排序
【发布时间】:2018-09-15 02:42:38
【问题描述】:

我有一个示例字符向量,其文件名如下:

> vector
[1] "1 Janu 1998.txt"        "2 Feb. 1999.txt"   "3 Marc 1999.txt" 
[4] "2 February 1998.txt"    "3 March. 1998.txt" "1 Jan 1999.txt" 

我想按年和月(每个元素的第一个数字)对元素进行排序。所以我这样做:

> library(gtools)
> mixedsort(vector)
[1] "1 Janu 1998.txt"    "1 Jan 1999.txt"    "2 February 1998.txt"   
[4] "2 Feb. 1999.txt"    "3 Marc 1999.txt"   "3 March. 1998.txt"

如果我使用 sort(vector),我会得到相同的输出。我一直在阅读几个问题,但我还没有找到具体的答案。如果有人可以帮助我,我将不胜感激。提前致谢。 我想得到以下输出:

> output
[1] "1 Janu 1998.txt"    "2 February 1998.txt"    "3 March. 1998.txt"       
[4] "1 Jan 1999.txt"     "2 Feb. 1999.txt"        "3 Marc 1999.txt"  

【问题讨论】:

  • 你能举一个你想要的输出的例子吗?
  • 很抱歉,但更改输入数据会使这成为一个完全不同的问题/问题!另外,您对那些试图根据您的原始样本数据提供帮助的 SO 用户非常不尊重。您有哪些月份名称的非标准缩写以及多少个非标准缩写?我们(以及 R)应该如何知道?以前使用strptime 进行解析是直截了当的;现在这成为解释/映射月份名称的非标准缩写的问题。
  • 很抱歉,莫里茨。我想纠正我的错误。我有很多不标准的缩写,所以我一直在寻找一种方法来定期解决这个问题

标签: r sorting date vector


【解决方案1】:

我们可以做到:

v <- c("1 Jan 1998.txt", "2 Feb. 1999.txt", "3 March 1999.txt", "2 Feb 1998.txt", "3 March. 1998.txt","1 Jan 1999.txt")

v[order(as.Date(gsub("\\.", "", v), "%d %b %Ytxt"))];
#[1] "1 Jan 1998.txt"    "2 Feb 1998.txt"    "3 March. 1998.txt"
#[4] "1 Jan 1999.txt"    "2 Feb. 1999.txt"   "3 March 1999.txt"

解释:我们使用as.Date将向量v中的条目转换为日期;然后order 将按日、月、年正确排序日期。

请注意,向量v 中的某些条目包含月份之后的句点;不确定这是否是偶然的,但 gsub 命令会处理这些问题。

同样可以通过以下方式实现:

v[order(as.Date(gsub("(\\.|\\.txt)", "", v), "%d %b %Y"))];

更新

为了解决月份名称的非标准缩写,我将定义一个自定义map,它将非标准与标准名称/缩写联系起来。然后你可以这样做:

v <- c("1 Janu 1998.txt", "2 Feb. 1999.txt", "3 Marc 1999.txt",
    "2 February 1998.txt", "3 March. 1998.txt", "1 Jan 1999.txt")

# Define a map to map non-standard to standard month abbrev
map <- c(
    Janu = "Jan",
    Marc = "March")

# Separate dmy from filename and store in matrix
mat <- sapply(gsub("(\\.|\\.txt)", "", v), function(x)
    unlist(strsplit(x, " ")))

# Replace non-standard month names
mat[2, ] <- ifelse(
    !is.na(match(mat[2, ], names(map))),
    map[match(mat[2, ], names(map))],
    mat[2, ])

# Convert to Date then to numeric
dmy <- as.numeric(apply(mat, 2, function(x)
    as.Date(paste0(x, collapse = "-"), format = "%d-%b-%Y")));

# Order according to dmy
v[order(dmy)]
#[1] "1 Janu 1998.txt"     "2 February 1998.txt" "3 March. 1998.txt"
#[4] "1 Jan 1999.txt"      "2 Feb. 1999.txt"     "3 Marc 1999.txt"

【讨论】:

  • 谢谢你,莫里茨。你是对的,有些元素包含“。”月后。另一个问题是有月份的元素,例如:“Janu”、“Fe.”。我无法得到我想要的输出。你能告诉我解决这个问题的方法吗?
  • @Citizen 经期不是问题,正如我演示的那样;月份的非标准缩写是另一回事(也是一个不同的问题,因为您的样本数据没有显示这一点)。一般来说,始终提供代表性样本数据是绝对关键的;不幸的是,情况似乎并非如此。几个月的非标准缩写需要不同的方法来解析文件名,因为我们不能再依赖strptime(它在as.Date中进行解析)。
  • 对不起,莫里茨。我用一个更好的例子编辑了这个问题。非常感谢。
  • @Citizen 我已在我的解决方案中添加了更新,以说明非标准月份缩写。请看一下。对于您的完整数据,您必须扩展 map 以说明数据中的所有非标准月份名称。
  • 非常感谢,莫里茨。对不起我的错误。
猜你喜欢
  • 1970-01-01
  • 2015-02-08
  • 2021-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
相关资源
最近更新 更多