非常有趣的问题,答案隐藏在问题本身中。为了清楚起见,而不是更新相同的内容df
每次我都会使用df1
, df2
etc.
我们首先从数据开始。
id <- c("Johnboy","Johnboy","Johnboy")
orderno <- c(2,2,1)
validorder <- c(0,1,1)
ordertype <- c(95,94,95)
orderdate <- as.Date(c("2019-06-17","2019-03-26","2018-08-23"))
df <- data.frame(id, orderno, validorder, ordertype, orderdate)
library(dplyr)
Step 1 -
df1 <- df %>%
mutate(orderdate_dried = if_else(validorder == 1 &
ordertype == 95,
orderdate, as.Date(NA)),
orderdate_fresh = if_else(validorder == 1 &
ordertype == 94,
orderdate, as.Date(NA)))
df1
# id orderno validorder ordertype orderdate orderdate_dried orderdate_fresh
#1 Johnboy 2 0 95 2019-06-17 <NA> <NA>
#2 Johnboy 2 1 94 2019-03-26 <NA> 2019-03-26
#3 Johnboy 1 1 95 2018-08-23 2018-08-23 <NA>
这里一切都如预期。
Step 2 -
df2 <- df1 %>%
group_by(id, orderno) %>%
mutate(orderdate_dried = min(orderdate_dried, na.rm = TRUE),
orderdate_fresh = min(orderdate_fresh, na.rm = TRUE)) %>%
ungroup()
df2
# A tibble: 3 x 7
# id orderno validorder ordertype orderdate orderdate_dried orderdate_fresh
# <fct> <dbl> <dbl> <dbl> <date> <date> <date>
#1 Johnboy 2 0 95 2019-06-17 NA 2019-03-26
#2 Johnboy 2 1 94 2019-03-26 NA 2019-03-26
#3 Johnboy 1 1 95 2018-08-23 2018-08-23 NA
这里的一切似乎也都符合预期,我们得到NA
当组中没有其他日期时。
Step 3 -
df3 <- df2 %>%
group_by(id) %>%
mutate(max_orderdate_dried = max(orderdate_dried, na.rm=TRUE),
max_orderdate_fresh = max(orderdate_fresh, na.rm=TRUE)) %>%
ungroup()
df3
# A tibble: 3 x 9
# id orderno validorder ordertype orderdate orderdate_dried orderdate_fresh max_orderdate_dried max_orderdate_fresh
# <fct> <dbl> <dbl> <dbl> <date> <date> <date> <date> <date>
#1 Johnboy 2 0 95 2019-06-17 NA 2019-03-26 NA NA
#2 Johnboy 2 1 94 2019-03-26 NA 2019-03-26 NA NA
#3 Johnboy 1 1 95 2018-08-23 2018-08-23 NA NA NA
这里一切似乎都不对劲。这些基本上与您执行的步骤相同,并且这与您获得的输出相同,因此直到这里我们还没有做任何不同的事情。
但我们错过的一件事是在第 2 步中我们收到了一条警告消息。
警告消息:
1:在 min.default(c(NA_real_, NA_real_), na.rm = TRUE) 中:
min 没有非缺失参数;返回信息
2:在 min.default(NA_real_, na.rm = TRUE) 中:
min 没有非缺失参数;返回信息
因为我们在返回的组中没有非 NA 值Inf
即使输出df2
显示 NA (为什么它显示NA
当值为Inf
在答案末尾添加了对此的解释)。所以即使你测试is.na
有了它,它就失败了。
is.na(df2$orderdate_dried)
#[1] FALSE FALSE FALSE
Hence, max
with na.rm
也失败了。
max(df2$orderdate_dried, na.rm = TRUE)
#[1] NA
因此,你得到了所有NA
步骤 3 中的 s。
Solution
解决方案是检查is.finite
df3 <- df2 %>%
group_by(id) %>%
mutate(max_orderdate_dried = max(orderdate_dried[is.finite(orderdate_dried)], na.rm=TRUE),
max_orderdate_fresh = max(orderdate_fresh[is.finite(orderdate_fresh)], na.rm=TRUE)) %>%
ungroup()
df3
# A tibble: 3 x 9
# id orderno validorder ordertype orderdate orderdate_dried orderdate_fresh max_orderdate_dried max_orderdate_fresh
# <fct> <dbl> <dbl> <dbl> <date> <date> <date> <date> <date>
#1 Johnboy 2 0 95 2019-06-17 NA 2019-03-26 2018-08-23 2019-03-26
#2 Johnboy 2 1 94 2019-03-26 NA 2019-03-26 2018-08-23 2019-03-26
#3 Johnboy 1 1 95 2018-08-23 2018-08-23 NA 2018-08-23 2019-03-26
为什么它的值显示为NA
当值为Inf
?
在第2步中,我们基本上做的是
min(NA, na.rm = TRUE)
#[1] Inf
警告信息:
在 min(NA, na.rm = TRUE) 中:min 没有非缺失参数;返回信息
这返回Inf
我们收到一个警告。
但是,由于我们知道一列只能保存一个值class
.
class(Inf) #is
#[1] "numeric"
但我们有“日期”类的数据df1
's orderdate_dried
column
class(df1$orderdate_dried)
#[1] "Date"
so Inf
然后被强制进入返回的“Date”类。
as.Date(min(NA, na.rm = TRUE))
#[1] NA
这又是回报NA
但这不是真的NA
and is.na
在此失败
is.na(as.Date(min(NA, na.rm = TRUE)))
#[1] FALSE
因此,步骤 3 无法按预期工作。
我希望这个答案是清楚的,不要太混乱。