运行dplyr mutate语句时如何避免警告与Inf输出?
数据框出现Inf及警告的原因与解决方法
问题重现
运行以下代码后,数据框第4行的FixMinIfs列出现Inf(预期为0),同时收到警告:
library(dplyr) myDF <- data.frame( Name = c("R","R","B","R","X","X"), Code1 = c(0,0,0,0,1.1,1.2), Code2 = c(1,2,1,3,1,2) ) myDFRender <- myDF %>% mutate(FixSumIfs = sapply(1:n(), function(x) sum(Code2[1:n()][Code1[1:n()] < Code1[x]]))) %>% group_by(Code2) %>% mutate(FixMinIfs = min(Code1[Code1 > 0])) %>% ungroup() print.data.frame(myDFRender)
输出结果
Name Code1 Code2 FixSumIfs FixMinIfs 1 R 0.0 1 0 1.1 2 R 0.0 2 0 1.2 3 B 0.0 1 0 1.1 4 R 0.0 3 0 Inf 5 X 1.1 1 7 1.1 6 X 1.2 2 8 1.2
警告信息
Warning message:
Problem withmutate()columnFixMinIfs.
ℹFixMinIfs = min(Code1[Code1 > 0]).
ℹ no non-missing arguments to min; returning Inf
ℹ The warning occurred in group 3: Code2 = 3.
问题原因
- 按
Code2分组后,Code2=3的分组中,Code1的值只有0,执行Code1[Code1 > 0]会得到空向量; - R语言中,对空向量调用
min()函数时,默认返回Inf,同时抛出"no non-missing arguments to min"的警告; - 原代码未处理空向量的情况,导致不符合预期的
Inf输出。
解决方法
需要在计算最小值时,处理空向量场景,将其替换为预期的0。以下提供两种简洁实现方式:
方法1:用ifelse判断空向量
myDFRender <- myDF %>% mutate(FixSumIfs = sapply(1:n(), function(x) sum(Code2[Code1 < Code1[x]]))) %>% # 简化原代码的索引写法 group_by(Code2) %>% mutate(FixMinIfs = ifelse(length(Code1[Code1 > 0]) == 0, 0, min(Code1[Code1 > 0]))) %>% ungroup()
方法2:用coalesce结合na.rm参数
myDFRender <- myDF %>% mutate(FixSumIfs = sapply(1:n(), function(x) sum(Code2[Code1 < Code1[x]]))) %>% group_by(Code2) %>% mutate(FixMinIfs = coalesce(min(Code1[Code1 > 0], na.rm = TRUE), 0)) %>% ungroup()
说明
- 方法1先检查筛选后的向量长度,为空则返回0,否则返回最小值;
- 方法2中,
min(..., na.rm=TRUE)对空向量会返回NA,再用coalesce将NA替换为0; - 原代码中的
Code2[1:n()][Code1[1:n()] < Code1[x]]可简化为Code2[Code1 < Code1[x]],无需额外指定索引范围。
内容的提问来源于stack exchange,提问作者Village.Idyot
相关产品推荐
相关产品推荐

