【问题标题】:How do I write a function that converts character vector to date vector in R?如何在 R 中编写一个将字符向量转换为日期向量的函数?
【发布时间】:2014-11-19 15:50:28
【问题描述】:

这似乎是一个足够简单的函数来编写,但我认为我误解了形式参数的要求/R 如何解析和评估函数。

我正在尝试编写一个函数,将"%m/%d/%Y"(属于data.frame df)形式的任何字符向量转换为日期向量,并将其格式化为"%m/%d/%Y",如下所示:

dateformat <- function(x) {
  df$x <- (format(as.Date(df$x, format = "%m/%d/%Y"), "%m/%d/%Y"))
}

我在想……

dateformat(a)

... 将"a" 作为x 的实际参数并将其插入函数中,从而解析为:

 df$a <- (format(as.Date(df$a, format = "%m/%d/%Y"), "%m/%d/%Y"))

但是,在运行dateformat(a) 时出现以下错误:

Error in as.Date.default(df$x, format = "%m/%d/%Y") : 
  do not know how to convert 'df$x' to class “Date”

有人可以解释为什么我对形式/实际参数和/或 R 函数解析/评估的理解不正确吗?谢谢。

更新

当然,对于我想要转换为日期的所有变量(例如,df$a、df$b、df$c),我可以只写

df$a &lt;- (format(as.Date(df$a, format = "%m/%d/%Y"), "%m/%d/%Y"))

df$b &lt;- (format(as.Date(df$b, format = "%m/%d/%Y"), "%m/%d/%Y"))

df$c &lt;- (format(as.Date(df$c, format = "%m/%d/%Y"), "%m/%d/%Y"))

但我希望通过制作一个更通用的函数来提高我的编码技能,我可以向其中提供变量向量。例如,如果我有df$a 到df$z,我想转换为日期变量的所有字符变量怎么办?在我写了一个合适的函数之后,我可能会像这样运行它:

for (n in letters) {
  dateformat(n)
}

【问题讨论】:

  • 只需从公式中删除 df$x &lt;- 即可。还有你是怎么使用这个功能的?
  • @rawr 删除 df$x &lt;- 后我仍然遇到同样的错误。查看我的编辑以了解理由以及我如何使用该功能。
  • 函数中,x是通用输入,所以不需要df$x,只需x:dateformat &lt;- function(x) format(as.Date(x, format = "%m/%d/%Y"), "%m/%d/%Y")

标签: r


【解决方案1】:

首先,format(...) 函数返回一个字符向量,而不是日期,所以如果x 是一个字符串,

format(as.Date(x, format = "%m/%d/%Y"), "%m/%d/%Y")

将x 转换为日期,然后再转换回字符,如:

result <- format(as.Date("01/03/2014", format = "%m/%d/%Y"), "%m/%d/%Y")
result
# [1] "01/03/2014"
class(result)
# [1] "character"

其次,在函数中,在表达式的 LHS 上引用对象,例如 df,会导致 R 在函数范围内创建该对象。

a <- 2
f <- function(x) a <- x
f(3)
a
# [1] 2

在这里,我们将变量a 设置为2。然后在函数中我们新建一个变量,在函数作用域a,设置为x(3),函数返回时销毁。所以在全局环境中a还是2。

如果你坚持使用dateformat(...) 函数,这应该可以工作:

df <- data.frame(a=paste("01",1:10,"2014",sep="/"),
                 b=paste("02",11:20,"2014",sep="/"),
                 c=paste("03",21:30,"2014",sep="/"))

dateformat <- function(x) as.Date(df[[x]], format = "%m/%d/%Y")
for (n in letters[1:3]) df[[n]] <- dateformat(n)
sapply(df,class)
#      a      b      c 
# "Date" "Date" "Date" 

这样会更有效率:

df <- as.data.frame(lapply(df,as.Date,format="%m/%d/%Y"))

【讨论】:

  • 精彩的回应,@jlhoward。我不熟悉do.call(),但在谷歌搜索并比较lapply(df, as.Date, format = "%m/%d/%Y")、data.frame(lapply(df, as.Date, format = "%m/%d/%Y")) 和do.call(data.frame,lapply(df,as.Date,format="%m/%d/%Y")) 之后,似乎第二个和第三个选项做同样的事情。那为什么是do.call?
  • 是的,我过度使用do.call(...)。最好的方法是使用as.data.frame(...)。我编辑了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
  • 1970-01-01
  • 2016-05-03
  • 2021-11-11
相关资源
最近更新 更多