在整个列表中使用分支语句而不是在R中的单个项目

时间:2014-09-10 17:30:00

标签: r if-statement dataframe

这是对这个问题的跟进,虽然这里的问题与那个问题无关,Using apply functions instead of for and branching statements in R

我有一个数据框:

    Date       Close    Weekday        DayOfMonth
290 1991-02-22 365.65   Friday         22
295 1991-03-01 370.47   Friday          1
300 1991-03-08 374.95   Friday          8
305 1991-03-15 373.59   Friday         15
310 1991-03-22 367.48   Friday         22
314 1991-03-28 375.22 Thursday         28
319 1991-04-05 375.36   Friday          5
324 1991-04-12 380.40   Friday         12
329 1991-04-19 384.20   Friday         19
334 1991-04-26 379.02   Friday         26
339 1991-05-03 380.80   Friday          3

我想创建另一个名为WeekOfCycle的列,它根据月中的某天计算出给定日期的月份。我基于上述问题使用此功能。

as.integer(cut(data$DayOfMonth, c(-Inf, 7, 14, 21, 28, Inf)))

上述行适用于周五,周四应为

as.integer(cut(data$DayOfMonth, c(-Inf, 6, 13, 20, 27, Inf)))

期望的输出:

          Date  Close  Weekday DayOfMonth WeekOfCycle
290 1991-02-22 365.65   Friday         22           4
295 1991-03-01 370.47   Friday          1           1
300 1991-03-08 374.95   Friday          8           2
305 1991-03-15 373.59   Friday         15           3
310 1991-03-22 367.48   Friday         22           4
314 1991-03-28 375.22 Thursday         28           5
319 1991-04-05 375.36   Friday          5           1
324 1991-04-12 380.40   Friday         12           2
329 1991-04-19 384.20   Friday         19           3
334 1991-04-26 379.02   Friday         26           4
339 1991-05-03 380.80   Friday          3           1

我试图让这个与lapply函数一起工作,虽然它不起作用:

   data$WeekOfCycle <- with(data, lapply(Weekday, function(i){
                            if (i == "Friday"){
                               as.integer(cut(DayOfMonth, c(-Inf, 7, 14, 21, 28, Inf)))
                               }
                            else if (i == "Thursday"){
                              as.integer(cut(DayOfMonth, c(-Inf, 6, 13, 20, 27, Inf)))
                            }
                            }
                           ))

我觉得我很亲近,但我肯定错过了一些东西。理想情况下,即使没有if和else声明,我也愿意这样做,但我不知道如何做。

数据框的可重现代码:

structure(list(Date = structure(c(7722, 7729, 7736, 7743, 7750, 
7756, 7764, 7771, 7778, 7785, 7792), class = "Date"), Close = c(365.65, 
370.47, 374.95, 373.59, 367.48, 375.22, 375.36, 380.4, 384.2, 
379.02, 380.8), Weekday = c("Friday", "Friday", "Friday", "Friday", 
"Friday", "Thursday", "Friday", "Friday", "Friday", "Friday", 
"Friday"), DayOfMonth = c(22, 1, 8, 15, 22, 28, 5, 12, 19, 26, 
3)), .Names = c("Date", "Close", "Weekday", "DayOfMonth"), row.names = c(290L, 
295L, 300L, 305L, 310L, 314L, 319L, 324L, 329L, 334L, 339L), class = "data.frame")

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

如果您为样本数据包含所需的输出会有所帮助,这样我就可以检查我是否得到了您想要的结果,但是这个方法怎么样

#define the shift for each week day
offset<-c(Friday=0, Thursday=1)

#see how may times 7 does into the date of month
MonthWeek <- unname((data$DayOfMonth+offset[data$Weekday]-1) %/% 7 +1)

cbind(data, MonthWeek)
#           Date  Close  Weekday DayOfMonth MonthWeek
# 290 1991-02-22 365.65   Friday         22         4
# 295 1991-03-01 370.47   Friday          1         1
# 300 1991-03-08 374.95   Friday          8         2
# 305 1991-03-15 373.59   Friday         15         3
# 310 1991-03-22 367.48   Friday         22         4
# 314 1991-03-28 375.22 Thursday         28         5
# 319 1991-04-05 375.36   Friday          5         1
# 324 1991-04-12 380.40   Friday         12         2
# 329 1991-04-19 384.20   Friday         19         3
# 334 1991-04-26 379.02   Friday         26         4
# 339 1991-05-03 380.80   Friday          3         1

在这种特殊情况下,不需要复杂的if语句。通过一些非常简单的数学计算,一切都可以快速完成。