gpt4 book ai didi

r - 使用 dplyr::group_by() 使用 NA 查找最小日期

转载 作者:行者123 更新时间:2023-12-01 16:21:33 25 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





R `Inf` when it has class `Date` is printing `NA`

(1 个回答)


3年前关闭。




我正在寻找组内的最短日期。很多时候,该组只包含缺少的日期(在这种情况下,我更喜欢分配类似 NA 的内容)。
NA s 似乎被正确分配,但它们没有响应 is.na()正如我所料。 当单元格显示为 NA , is.na()输出意外为 FALSE。

library(magrittr)
ds_visit <- tibble::tribble(
~subject_id, ~date,
1L, as.Date("2017-01-01" ),
1L, as.Date("2017-02-01" ),

2L, as.Date(NA_character_),
2L, as.Date("2017-01-02" ),

3L, as.Date(NA_character_),
3L, as.Date(NA_character_),

4L, as.Date(NA_character_),
4L, as.Date(NA_character_)
)

ds_subject <- ds_visit %>%
# as.data.frame() %>%
dplyr::group_by(subject_id) %>%
dplyr::mutate(
date_na = is.na(date), # Works as expected
date_min = min(date, na.rm=T), # Works as expected

date_min_na = is.na(date_min) # Does NOT work as expected.
) %>%
dplyr::ungroup() # %>% as.data.frame()
ds_visit看起来正确。 ds_subject对我来说看起来是正确的,除了最后一列。

ds_subject(最后一列的最后四行是意外的。)
# A tibble: 8 x 5
subject_id date date_na date_min date_min_na
<int> <date> <lgl> <date> <lgl>
1 1 2017-01-01 F 2017-01-01 F
2 1 2017-02-01 F 2017-01-01 F
3 2 NA T 2017-01-02 F
4 2 2017-01-02 F 2017-01-02 F
5 3 NA T NA F # Should be 'T'?
6 3 NA T NA F # Should be 'T'?
7 4 NA T NA F # Should be 'T'?
8 4 NA T NA F # Should be 'T'?

我抖动了几个维度但没有成功,包括:(a) 操作系统,(b) R 版本(包括 3.4.3 patched),
(c) dplyr & rlang版本(包括 CRAN 和 GitHub 版本),以及 (d) tibble对比 data.frame .作为临时解决方法(此处未显示),我在找到最小值之前将日期转换为字符,然后转换回日期。

警告消息(从主题 3 和 4 生成):即使警告消息说 Inf被退回, NA打印数据集时出现。 (此行为与 min(as.Date(NA), na.rm=T) 一致)。
1: In min.default(c(NA_real_, NA_real_), na.rm = TRUE) :
no non-missing arguments to min; returning Inf
2: In min.default(c(NA_real_, NA_real_), na.rm = TRUE) :
no non-missing arguments to min; returning Inf

进一步检查日期列似乎与上面的数据集 View 一致。类型是日期,最后四个单元格是 NA ,不是无穷大。
> str(ds_subject$date_min)
Date[1:8], format: "2017-01-01" "2017-01-01" "2017-01-02" "2017-01-02" NA NA NA NA

这是一个错误,还是我滥用了某些东西?这是否相关 NA被生产而不是无限?

编辑 1

@eipi10 和@mtoto 下面的链接帮助我更好地理解。谢谢。我对打印 'NA' 而不是 'Inf' 并不感到兴奋,但我会尽量记住这一点。

为了解决这种特定情况,是否有比 base::min() 更好的功能? ?

我想要一个可以包含在 dplyr::mutate() 中的函数/ dplyr::summarize() 行为类似于 SQL 的子句。 (当 is.na() 替换 summarize() 时,最初的 dplyr 示例仍然存在 mutate() 问题)。

例如:
"
SELECT
subject_id,
MIN(date) AS date_min
--MIN(date) OVER (PARTITION BY subject_id) AS date_min --`OVER` not supported by sqlite
FROM ds_visit
GROUP BY subject_id
" %>%
sqldf::sqldf() %>%
tibble::as_tibble() %>%
dplyr::mutate(
# date_min_na_1 = is.na(date_min), #Before conversion back to date (from numeric); same result as below.
date_min = as.Date(date_min, "1970-01-01"),
date_min_na = is.na(date_min)
)

结果哪里缺组有礼貌 NA按预期响应 is.na() 的值:
# A tibble: 4 x 3
subject_id date_min date_min_na
<int> <date> <lgl>
1 1 2017-01-01 F
2 2 2017-01-02 F
3 3 NA T
4 4 NA T

编辑 2

我看到这个问题被标记为 R Inf when it has class Date is printing NA 的重复.我看到了很多重叠(我从那个问题中学到了很多东西,以及它对我的初始代码有什么影响),但我相信它们是不同的问题。

本题涉及分组,返回 NA当不存在非缺失值时。我只对 base::min() 不感兴趣.如上所述,理想情况下 base::min()完全避免使用已建立且经过测试的功能/方法,其行为更像 SQL。

(尽管我很感激 @alistaire 在 base:min() 周围的包装器,如果不存在已建立的功能/方法,我会使用它。)

最佳答案

问题是minna.rm = TRUE和所有- NA值返回 Inf ( max 等效返回 -Inf ),但 print.Date没有办法显示这些值,所以它打印为 NA ,即使这不是存储值。

min(NA, na.rm = TRUE)
#> Warning in min(NA, na.rm = TRUE): no non-missing arguments to min;
#> returning Inf
#> [1] Inf

x <- min(as.Date(NA), na.rm = TRUE)
#> Warning in min.default(structure(NA_real_, class = "Date"), na.rm = TRUE):
#> no non-missing arguments to min; returning Inf

x
#> [1] NA

is.na(x)
#> [1] FALSE

x == Inf
#> [1] TRUE

如果您愿意,您可以重新定义打印方法,以便根据您的喜好进行打印,例如

print.Date <- function(x, ...){
if(x == Inf | x == -Inf) {
print(as.numeric(x))
} else {
base::print.Date(x, ...)
}
}

x
#> [1] Inf

要实际获得您想要的结果,请指定如果所有值都为 NA 应返回的内容:

library(tidyverse)

ds_visit <- data_frame(subject_id = c(1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L),
date = as.Date(c("2017-01-01", "2017-02-01", NA, "2017-01-02", NA, NA, NA, NA)))

ds_visit %>%
group_by(subject_id) %>%
summarise(date_min = if(all(is.na(date))) NA else min(date, na.rm = TRUE),
date_min_na = is.na(date_min))
#> # A tibble: 4 x 3
#> subject_id date_min date_min_na
#> <int> <date> <lgl>
#> 1 1 2017-01-01 FALSE
#> 2 2 2017-01-02 FALSE
#> 3 3 NA TRUE
#> 4 4 NA TRUE

它并不那么简洁,但其行为完全可以预测。

关于r - 使用 dplyr::group_by() 使用 NA 查找最小日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48470746/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com