首页 > 解决方案 > 在R中的函数内循环

问题描述

我想创建一个包含 ifelse 语句的函数,如下所示:

ArrearsL1M<-function(input1, input2, input3, input4){
  output=0
  output=ifelse((df[[input1]] %in% c(1,2,3,4,5)),1,
                ifelse((df[[input2]] %in% c(1,2,3,4,5)),1,
                       ifelse((df[[input3]] %in% c(1,2,3,4,5)),1,
                              ifelse((df[[input4]] %in% c(1,2,3,4,5)), 1, 0))))
  return(output)

然后我会有这个:

df$Arrears_L1M<-ArrearsL1M("col_201823","col_201822","col_201821","col_201820")

以下是数据示例:

  col_201823 col_201822 col_201821 col_201820 col_201819 col_201818 col_201817 col_201816 col_201815
1         99          5          4          2         99         99         99         99         99
2          3          0          3          2          3          3          3          3          3
3          2          2          2          2          2          2          2          2          2
4          0          0          0          1          0          0          0          0          0
5         99         99          5         99         99         99         99         99         99
6          2          1          4         99          2          2          2          2          2
7          1          1         99         99          1          1          1          1          1

因此代码将从最近的开始检查前 4 周的数据(即 2018 年第 23 周、第 22 周、第 21 周和第 20 周)

开始的一周可以改变,我想让这个工作,以便我进入第一周并运行过去 4 周的功能。我只想输入第一周,所以只有一个输入。因此,如果我输入 col_201820,我将得到 col_201820、col_201819、col_201818 和 col_201817 周的答案。

我想在某个时间点运行 52 周的数据(即一年),所以如果开始周发生变化,我会尝试使其更容易更改。如果起始周为 201801,则还需要转到 201752、201751、201750。

我不确定从哪里开始,所以无法向您展示我已经尝试过的任何东西。

** 可重现示例的代码

col_201823<-c(99,3,2,0,99,2,1)
col_201822<-c(5,0,2,0,99,1,1)
col_201821<-c(4,3,2,0,5,4,99)
col_201820<-c(2,2,2,1,99,99,99)
col_201819<-c(99,3,2,0,99,2,1)
col_201818<-c(99,3,2,0,99,2,1)
col_201817<-c(99,3,2,0,99,2,1)
col_201816<-c(99,3,2,0,99,2,1)
col_201815<-c(99,3,2,0,99,2,1)

test<-as.data.frame(cbind(col_201823,col_201822,col_201821,col_201820,col_201819,col_201818,col_201817,col_201816,col_201815))

标签: rfunctionloopsif-statement

解决方案


我想你想知道如何从开始的一周创建一个周向量。例如

weeks_from_start <- function(x) {
    week <- as.integer(substring(x, nchar(x) - 1))
    rest <- substring(x, 1, nchar(x) - 2)
    paste0(rest, seq(week, by = -1, length.out=4))
}

所以

> weeks_from_start("col_201823")
[1] "col_201823" "col_201822" "col_201821" "col_201820"

ArrearsL1M()在函数的顶部使用它。我会将其实现为

ArrearsL1M <- function(df, last_week) {
    weeks <- weeks_from_start(last_week)
    m <- as.matrix(df[, weeks])
    m[] <- m %in% 1:5               # test all elements in 1 call; format as matrix
    rowSums(m) != 0
}

对于更复杂的解析,修改weeks_from_start()

week0 <- as.integer(substring(x, nchar(x) - 1))
year0 <- as.integer(substring(x, 5, 8))

week0 <- seq(week0, by = -1, length.out = 4)
week <- (week0 - 1) %% 52 + 1
year <- year0 - cumsum(week0 == 0)
sprintf("col_%4d%.2d", year, week)

可能这正在接近“黑客”,例如,所有年份都有 52 周吗?对于从周二开始的一年,是否是第 1 周周二 - 周日,上一年的第 52 周只是周一?是时候重新考虑如何表示这些数据了……


推荐阅读