将行返回给函数
Returning Row to a function
我正在尝试创建一个矩阵,判断日期是否在我的两列 Data$StartDate 和 Data$EndDate 创建的范围内。为此,我创建了以下函数
DatesChecked <- as.character(seq(as.Date("2012-06-30"), as.Date("2017-12-09"), by = "day"))
CheckOpen <- function(x, row, column){
if (Data$StartDate[row] > as.Date(column)) {
return(0)
} else {
if (is.na(Data$EndDate[row])) {
return(1)
} else {
ifelse(Data$EndDate > as.Date(column), return(1), return(0))
}
}
}
Data[,DatesChecked] <- mapply(CheckOpen, Data[,DatesChecked])
但是我不确定如何将行索引作为参数传递给我的函数。我把 "row" 作为填充物。
但最终,我强烈怀疑我采取了完全错误的方法。接下来我要做的是将每一列的总和作为一个新列放回 "DatesChecked" 中,这似乎是一个过于复杂的方法(即我正在计算每个日期有多少行的范围)。
示例数据:
StartDate EndDate
<dttm> <dttm>
1 2012-10-16 2014-02-19
2 2012-10-17 2013-04-16
3 2012-11-05 2013-04-22
4 2012-11-14 2013-05-01
5 2013-03-20 2013-08-29
6 2013-04-07 2013-09-09
在标题为“2014-01-01”的列中,结果将是 c(1,0,0,0,0,0)
,因为第一行是唯一落在该范围内的行。
下面是一个比较简单明了的解决方案。
DatesChecked <- seq(as.Date("2012-06-30"), as.Date("2017-12-09"), by = "day")
# summing TRUEs is like summing ones
cbind.data.frame(
DatesChecked,
sapply(DatesChecked, function(x) {
sum(x > Data$StartDate & x < Data$EndDate)
})
)
这是一种方法。首先,编写一个函数来检查特定日期 x
是否介于其他两个日期 d1
和 d2
之间。
check <- function(x, d1, d2) ifelse(x >= d1 & x <= d2, 1, 0)
然后加载 tidyverse,并使用 purrr::map
遍历所有选中的日期,将名称设置为日期,然后将所有列绑定在一起。
library(tidyverse)
df_checked <- map(DatesChecked, ~check(., d$StartDate, d$EndDate)) %>%
set_names(DatesChecked) %>%
bind_cols()
# Show first five columns
df_checked[ ,1:5]
# A tibble: 6 x 5
`2012-06-30` `2012-07-01` `2012-07-02` `2012-07-03` `2012-07-04`
<dbl> <dbl> <dbl> <dbl> <dbl>
1 0 0 0 0 0
2 0 0 0 0 0
3 0 0 0 0 0
4 0 0 0 0 0
5 0 0 0 0 0
6 0 0 0 0 0
# Show specific column mentioned in question
df_checked["2014-01-01"]
# A tibble: 6 x 1
`2014-01-01`
<dbl>
1 1.00
2 0
3 0
4 0
5 0
6 0
我正在尝试创建一个矩阵,判断日期是否在我的两列 Data$StartDate 和 Data$EndDate 创建的范围内。为此,我创建了以下函数
DatesChecked <- as.character(seq(as.Date("2012-06-30"), as.Date("2017-12-09"), by = "day"))
CheckOpen <- function(x, row, column){
if (Data$StartDate[row] > as.Date(column)) {
return(0)
} else {
if (is.na(Data$EndDate[row])) {
return(1)
} else {
ifelse(Data$EndDate > as.Date(column), return(1), return(0))
}
}
}
Data[,DatesChecked] <- mapply(CheckOpen, Data[,DatesChecked])
但是我不确定如何将行索引作为参数传递给我的函数。我把 "row" 作为填充物。
但最终,我强烈怀疑我采取了完全错误的方法。接下来我要做的是将每一列的总和作为一个新列放回 "DatesChecked" 中,这似乎是一个过于复杂的方法(即我正在计算每个日期有多少行的范围)。
示例数据:
StartDate EndDate
<dttm> <dttm>
1 2012-10-16 2014-02-19
2 2012-10-17 2013-04-16
3 2012-11-05 2013-04-22
4 2012-11-14 2013-05-01
5 2013-03-20 2013-08-29
6 2013-04-07 2013-09-09
在标题为“2014-01-01”的列中,结果将是 c(1,0,0,0,0,0)
,因为第一行是唯一落在该范围内的行。
下面是一个比较简单明了的解决方案。
DatesChecked <- seq(as.Date("2012-06-30"), as.Date("2017-12-09"), by = "day")
# summing TRUEs is like summing ones
cbind.data.frame(
DatesChecked,
sapply(DatesChecked, function(x) {
sum(x > Data$StartDate & x < Data$EndDate)
})
)
这是一种方法。首先,编写一个函数来检查特定日期 x
是否介于其他两个日期 d1
和 d2
之间。
check <- function(x, d1, d2) ifelse(x >= d1 & x <= d2, 1, 0)
然后加载 tidyverse,并使用 purrr::map
遍历所有选中的日期,将名称设置为日期,然后将所有列绑定在一起。
library(tidyverse)
df_checked <- map(DatesChecked, ~check(., d$StartDate, d$EndDate)) %>%
set_names(DatesChecked) %>%
bind_cols()
# Show first five columns
df_checked[ ,1:5]
# A tibble: 6 x 5
`2012-06-30` `2012-07-01` `2012-07-02` `2012-07-03` `2012-07-04`
<dbl> <dbl> <dbl> <dbl> <dbl>
1 0 0 0 0 0
2 0 0 0 0 0
3 0 0 0 0 0
4 0 0 0 0 0
5 0 0 0 0 0
6 0 0 0 0 0
# Show specific column mentioned in question
df_checked["2014-01-01"]
# A tibble: 6 x 1
`2014-01-01`
<dbl>
1 1.00
2 0
3 0
4 0
5 0
6 0