dplyr 在改变数据帧时将日期变成双倍
dplyr is turning dates to doubles when mutating dataframe
我正在使用带有日期和时间的数据框。我需要将某些日期列设置为 NA
,但是当我使用 mutate
函数时,日期列变成了双列!
示例:
df
## my_date_01 my_date_02
## <date> <date>
## 1 2018-09-13 NA
## 2 NA 2018-12-09
## 3 NA 2018-12-16
## 4 NA 2019-01-19
## 5 NA 2018-11-19
## 6 NA 2018-12-16
## 7 NA 2018-08-08
## 8 NA 2018-10-24
## 9 2019-03-26 NA
##10 NA 2018-12-11
df %>% mutate(my_date_01 = ifelse(my_date_01 > lubridate::date("2019-01-01"),
NA,
my_date_01))
## my_date_01 my_date_02
## <dbl> <date>
## 1 17787 NA
## 2 NA 2018-12-09
## 3 NA 2018-12-16
## 4 NA 2019-01-19
## 5 NA 2018-11-19
## 6 NA 2018-12-16
## 7 NA 2018-08-08
## 8 NA 2018-10-24
## 9 NA NA
##10 NA 2018-12-11
这里发生了两件事:
- 所需的日期确实被替换为
NA
(这没问题),但是
- 整个列正在转换为双精度(这是非常错误)
我错过了什么?
我们可以包装 as.Date(NA)
以获得相同的类型,同时进行比较
library(dplyr)
df %>%
mutate(my_date_01 = case_when(my_date_01 > lubridate::date("2019-01-01")
~ as.Date(NA),
TRUE ~my_date_01))
# my_date_01 my_date_02
#1 2018-09-13 <NA>
#2 <NA> 2018-12-09
#3 <NA> 2018-12-16
#4 <NA> 2019-01-19
#5 <NA> 2018-11-19
#6 <NA> 2018-12-16
#7 <NA> 2018-08-08
#8 <NA> 2018-10-24
#9 <NA> <NA>
#10 <NA> 2018-12-11
上面的修复可能仍然不适用于 ifelse
,因为在 ifelse
的源代码中
...
ans <- test # assigned to logical vector test
len <- length(ans)
ypos <- which(test)
npos <- which(!test)
if (length(ypos) > 0L)
ans[ypos] <- rep(yes, length.out = len)[ypos]
if (length(npos) > 0L)
ans[npos] <- rep(no, length.out = len)[npos]
ans
}
如果是
ans <- as.Date(rep(NA, length(test)))
它可以与下面的代码一起使用,因为逻辑向量在执行赋值时被强制转换为数字,而上述 as.Date
步骤不会发生这种情况
df %>%
mutate(my_date_01 = ifelsenew(my_date_01 > lubridate::date("2019-01-01"),
as.Date(NA),
my_date_01))
数据
df <- structure(list(my_date_01 = structure(c(17787, NA, NA, NA, NA,
NA, NA, NA, 17981, NA), class = "Date"), my_date_02 = structure(c(NA,
17874, 17881, 17915, 17854, 17881, 17751, 17828, NA, 17876), class = "Date")),
row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10"), class = "data.frame")
我正在使用带有日期和时间的数据框。我需要将某些日期列设置为 NA
,但是当我使用 mutate
函数时,日期列变成了双列!
示例:
df
## my_date_01 my_date_02
## <date> <date>
## 1 2018-09-13 NA
## 2 NA 2018-12-09
## 3 NA 2018-12-16
## 4 NA 2019-01-19
## 5 NA 2018-11-19
## 6 NA 2018-12-16
## 7 NA 2018-08-08
## 8 NA 2018-10-24
## 9 2019-03-26 NA
##10 NA 2018-12-11
df %>% mutate(my_date_01 = ifelse(my_date_01 > lubridate::date("2019-01-01"),
NA,
my_date_01))
## my_date_01 my_date_02
## <dbl> <date>
## 1 17787 NA
## 2 NA 2018-12-09
## 3 NA 2018-12-16
## 4 NA 2019-01-19
## 5 NA 2018-11-19
## 6 NA 2018-12-16
## 7 NA 2018-08-08
## 8 NA 2018-10-24
## 9 NA NA
##10 NA 2018-12-11
这里发生了两件事:
- 所需的日期确实被替换为
NA
(这没问题),但是 - 整个列正在转换为双精度(这是非常错误)
我错过了什么?
我们可以包装 as.Date(NA)
以获得相同的类型,同时进行比较
library(dplyr)
df %>%
mutate(my_date_01 = case_when(my_date_01 > lubridate::date("2019-01-01")
~ as.Date(NA),
TRUE ~my_date_01))
# my_date_01 my_date_02
#1 2018-09-13 <NA>
#2 <NA> 2018-12-09
#3 <NA> 2018-12-16
#4 <NA> 2019-01-19
#5 <NA> 2018-11-19
#6 <NA> 2018-12-16
#7 <NA> 2018-08-08
#8 <NA> 2018-10-24
#9 <NA> <NA>
#10 <NA> 2018-12-11
上面的修复可能仍然不适用于 ifelse
,因为在 ifelse
...
ans <- test # assigned to logical vector test
len <- length(ans)
ypos <- which(test)
npos <- which(!test)
if (length(ypos) > 0L)
ans[ypos] <- rep(yes, length.out = len)[ypos]
if (length(npos) > 0L)
ans[npos] <- rep(no, length.out = len)[npos]
ans
}
如果是
ans <- as.Date(rep(NA, length(test)))
它可以与下面的代码一起使用,因为逻辑向量在执行赋值时被强制转换为数字,而上述 as.Date
步骤不会发生这种情况
df %>%
mutate(my_date_01 = ifelsenew(my_date_01 > lubridate::date("2019-01-01"),
as.Date(NA),
my_date_01))
数据
df <- structure(list(my_date_01 = structure(c(17787, NA, NA, NA, NA,
NA, NA, NA, 17981, NA), class = "Date"), my_date_02 = structure(c(NA,
17874, 17881, 17915, 17854, 17881, 17751, 17828, NA, 17876), class = "Date")),
row.names = c("1",
"2", "3", "4", "5", "6", "7", "8", "9", "10"), class = "data.frame")