我正在尝试使用循环创建日期向量(格式化为字符串而不是日期)for.我已经回顾了其他一些SO问题,例如(如何使用循环创建字符串向量?),但它们没有帮助.我创建了以下for循环:
start_dates <- c("1993-12-01")
j <- 1
start_dates <- for(i in 1994:as.numeric(format(Sys.Date(), "%Y"))){
date <- sprintf("%s-01-01", i)
j <- j + 1
start_dates[j] <- date
}
Run Code Online (Sandbox Code Playgroud)
但是,它返回一个NULL (empty)向量start_dates.当我i手动增加索引时,它可以工作.例如:
> years <- 1994:as.numeric(format(Sys.Date(), "%Y"))
> start_dates <- c("1993-12-01")
> j <- 1
> i <- years[1]
> date <- sprintf("%s-01-01", i)
> j <- j + 1
> start_dates[j] <- date
> start_dates
[1] "1993-12-01" "1994-01-01"
> i <- years[2]
> date <- sprintf("%s-01-01", i)
> j <- j + 1
> start_dates[j] <- date
> start_dates
[1] "1993-12-01" "1994-01-01" "1995-01-01"
Run Code Online (Sandbox Code Playgroud)
它必须与我的for()陈述的构造有关,但我无法弄清楚.我确信它非常简单.提前致谢.
出什么问题了:
sprintf("%s-01-01", 1994:2015)
> sprintf("%s-01-01", 1994:2015)
[1] "1994-01-01" "1995-01-01" "1996-01-01" "1997-01-01" "1998-01-01"
[6] "1999-01-01" "2000-01-01" "2001-01-01" "2002-01-01" "2003-01-01"
[11] "2004-01-01" "2005-01-01" "2006-01-01" "2007-01-01" "2008-01-01"
[16] "2009-01-01" "2010-01-01" "2011-01-01" "2012-01-01" "2013-01-01"
[21] "2014-01-01" "2015-01-01"
Run Code Online (Sandbox Code Playgroud)
sprintf() 完全矢量化,利用这一点.
主要的问题是,你分配的价值for()功能,start_dates当for()完成的,因此,覆盖所有的努力你的循环一样.这实际上是发生了什么:
j <- 1
foo <- for (i in 1:10) {
j <- j + 1
}
foo
> foo
NULL
Run Code Online (Sandbox Code Playgroud)
阅读?'for'我们看到这种行为是设计的:
Value:
....
‘for’, ‘while’ and ‘repeat’ return ‘NULL’ invisibly.
Run Code Online (Sandbox Code Playgroud)
解决方案:不要分配返回的值for().因此模板可能是:
for(i in foo) {
# ... do stuff
start_dates[j] <- bar
}
Run Code Online (Sandbox Code Playgroud)
解决这个问题,你仍然有问题; j将在2您开始时将第一个日期分配给输出j <- 1并在循环中分配之前递增它.
如果您i从序列1,2,...,n中获取值而不是您想要的实际年份,这将更容易.您可以使用i索引年份向量并将其作为元素的索引start_dates.
不是说你应该这样做循环,但是,如果你也想 ...
years <- seq.int(1994, 2015)
start_dates <- numeric(length = length(years))
for (i in seq_along(years)) {
start_dates[i] <- sprintf("%s-01-01", years[i])
}
Run Code Online (Sandbox Code Playgroud)
这会给:
> start_dates
[1] "1994-01-01" "1995-01-01" "1996-01-01" "1997-01-01" "1998-01-01"
[6] "1999-01-01" "2000-01-01" "2001-01-01" "2002-01-01" "2003-01-01"
[11] "2004-01-01" "2005-01-01" "2006-01-01" "2007-01-01" "2008-01-01"
[16] "2009-01-01" "2010-01-01" "2011-01-01" "2012-01-01" "2013-01-01"
[21] "2014-01-01" "2015-01-01"
Run Code Online (Sandbox Code Playgroud)
有时循环遍历向量中的实际值(就像你做的那样)而不是它的索引(正如我刚才所做的那样)是有帮助的,但仅限于特定情况.对于像这里一样的一般操作,这只是一个需要解决的额外复杂功能.也就是说,考虑在使用循环之前在R中进行向量化操作.