我遇到过这个问题。我想确定下个100年每个月的第二个星期日的日子。这是我的代码
x <- seq(as.Date("2014-9-01"),as.Date("2014-9-01")+100*365.25,1)
y <- format(x,"%Y%m")
xx <- NULL
for(i in unique(y)) {
w <- which(y == i)
xx <- c(xx,x[w[which(weekdays(x[w]) == "Sunday")[2]]])
}
head(xx)
tail(xx)
我已经实现了它但我不得不使用循环。如何使用矢量化代码更有效地完成此操作?
一般情况下,假设有一个带有 n 不同值的向量 v ,如何为每个不同的v值分配一个增加值,从每个不同的值开始为1值。也就是说,假设我从向量
开始v <- c(1,1,1,2,2,2,2,3,4,4)
我想生成&#34;运行计数器&#34;, v.counter , v
中的唯一值v.counter <- c(1,2,3,1,2,3,4,1,1,2)
显然我可以写一个循环来做到这一点。但是我如何用矢量化代码呢?
答案 0 :(得分:8)
您可以使用dplyr
执行运行计数:
library(dplyr)
dat = data.frame(x=rep(1:10, each=3))
dat = dat %>%
group_by(x) %>%
mutate(x_count=1:n())
x x_count
1 1 1
2 1 2
3 1 3
4 2 1
5 2 2
6 2 3
...
25 9 1
26 9 2
27 9 3
28 10 1
29 10 2
30 10 3
答案 1 :(得分:4)
对于生成组特定值,使用ave()
函数应该相当简单。
ave(v, v, FUN=seq_along)
# [1] 1 2 3 1 2 3 4 1 1 2
如果您只想在v
中查看连续序列而不是唯一值,那么您也可以这样做
v <- c(1,1,1,2,2,2,2,1,2,2)
ave(v, with(rle(v), rep(1:length(lengths), lengths)), FUN=seq_along)
# [1] 1 2 3 1 2 3 4 1 1 2
尽管v
中只使用了两个不同的值,但给出了相同的值。第一个解决方案将继续计算在遇到第二次时1离开的位置。另外,如果v
不是数字,则可以执行
v <- rep(letters[1:4], c(3,4,1,2))
ave(seq_along(v), v, FUN=seq_along)
# [1] 1 2 3 1 2 3 4 1 1 2
仍然可以获得数值。
答案 2 :(得分:3)
假设我们有一个包含v
的数据框:
data <- data.frame(v = c(1,1,1,2,2,2,2,3,4,4))
然后,使用dplyr
library(dplyr)
data %>%
group_by(v) %>%
mutate(v.counter = row_number())
答案 3 :(得分:2)
有很多好的答案。我留下以下内容,以获得每个月的第二个星期日,接下来的100年。我确信有更好的方法来处理日期类对象。但这也有效。
library(lubridate)
library(dplyr)
library(tidyr)
x <- seq(as.Date("2014-9-01"),as.Date("2014-9-01")+100*365.25,1)
weekday <- wday(x)
foo <- data.frame(x, weekday, stringsAsFactors = FALSE)
ana <- foo %>%
separate(x, c("year", "month", "date"), sep = "-") %>%
filter(weekday == 1) %>%
group_by(year, month) %>%
filter(row_number() == 2) %>%
unite(sunday, year, month, date, sep = "-") %>%
mutate(sunday = as.Date(sunday)) %>% ### If you want date object
select(sunday) ### If you want just one column
head(ana)
Source: local data frame [6 x 1]
sunday
1 2014-09-14
2 2014-10-12
3 2014-11-09
4 2014-12-14
5 2015-01-11
6 2015-02-08
答案 4 :(得分:1)
为了完成,我想添加data.table解决方案
dt <- data.table(x,y)
dt[, wd := weekdays(x)]
dt <- dt[, wdidx := seq_along(.I), by = c("y", "wd")][wd == "Sonntag" & wdidx == 2,]
head(dt, 20)
“Sonntag”意味着星期日,weekdays()
错综复杂的工作日回归工作日