使用R中的min()返回NA而不是Inf

Fre*_*ick 3 r min plyr dplyr

请考虑以下事项:

我最近"发现"的真棒plyrdplyr包装,并利用这些分析患者数据,提供给我的数据帧.这样的数据框可能如下所示:

df <- data.frame(id = c(1, 1, 1, 2, 2), # patient ID
                 diag = c(rep("dia1", 3), rep("dia2", 2)), # diagnosis
                 age = c(7.8, NA, 7.9, NA, NA)) # patient age
Run Code Online (Sandbox Code Playgroud)

我想总结一下中位数和平均值的所有患者的最小患者年龄.我做了以下事情:

min.age <- df %>% 
  group_by(id) %>% 
  summarise(min.age = min(age, na.rm = T))
Run Code Online (Sandbox Code Playgroud)

由于NAs数据框中有我收到警告:

`Warning message: In min(age, na.rm = T) :
no non-missing arguments to min; returning Inf`
Run Code Online (Sandbox Code Playgroud)

随着Inf我不能叫summary(df$min.age)以有意义的方式.

使用pmin()而不是min返回错误消息:

Error in summarise_impl(.data, dots) :
 Column 'in.age' must be length 1 (a summary value), not 3
Run Code Online (Sandbox Code Playgroud)

我可以做些什么来避免任何问题Inf,而是让NA我可以进一步继续: summary(df$min.age)

非常感谢!

ngm*_*ngm 8

您的代码执行以下操作:

  1. 将数据框分成组id
  2. min每个组内的函数应用于age变量,并na.rm=TRUE启用该选项。

因此,对于id1您得到,这与 7.8 相同min(c(7.8, NA, 7.9), na.rm=TRUE)min(c(7.8, 7.9))

然后,对于id2得到min(c(NA, NA), na.rm=TRUE),这与 相同min(c())

现在,空集的最小值是多少?“最小值”的定义是“小于集合中所有值的值”,并且当 B 是 A 的子集时,必须满足 min(A) <= min(B) 的性质。定义最小值的一种方法空集就是说它是“无穷大”,这就是 R 处理这种情况的方式。

你真的无法避免陷入Inf这种境地。但是您可以将另一个添加mutate到您的链中以将任何内容更改Inf为您喜欢的任何内容,例如NA.


df %>% group_by(id) %>% summarize(min_age = min(age, na.rm = TRUE)) %>% 
    mutate(min_age = ifelse(is.infinite(min_age), NA, min_age))
Run Code Online (Sandbox Code Playgroud)


awc*_*olm 5

您可以使用它is.infinite()来检测无穷大并ifelse有条件地将它们设置为NA.

#using your df and the dplyr package
min.age <- 
  df %>% 
  group_by(id) %>% 
  summarise(min.age = min(age, na.rm = T)) %>%
  mutate(min.age = ifelse(is.infinite(min.age), NA, min.age))
Run Code Online (Sandbox Code Playgroud)


dav*_*job 5

一个更简单的解决方案是 hablar 包中的 s 函数。在以最小/最大计算之前,它用 NA 替换空向量。@awchisholm 的代码块可能是:

library(hablar)

min.age <- df %>% 
  group_by(id) %>% 
  summarise(min.age = min(s(age)))
Run Code Online (Sandbox Code Playgroud)

免责声明自从我编写了这个包以来,我对这个解决方案有偏见。