[英]How to remove rows with inf from a dataframe in R
我有一个非常大的数据框( df ),大约有 35-45 列(变量)和大于 300 的行。有些行在单个或多个变量中包含 NA、NaN、Inf、-Inf 值,我使用了na.omit(df)
删除带有 NA 和 NaN 的行,但我无法使用na.omit函数删除带有 Inf 和 -Inf 值的行。
在搜索时,我遇到了这个线程Remove rows with Inf and NaN in R并使用了修改后的代码df[is.finite(df)]
但它没有删除带有 Inf 和 -Inf 的行,也给出了这个错误
is.finite(df) 中的错误:未为类型“list”实现默认方法
已编辑
即使对应的一列或多列有 inf 和 -inf 也删除整行
要删除带有 +/- Inf
的行,我建议如下:
df <- df[!is.infinite(rowSums(df)),]
或者,等效地,
df <- df[is.finite(rowSums(df)),]
第二个选项(带有is.finite()
而没有否定的选项)也会删除包含NA
值的行,以防这还没有完成。
根据数据,有几个使用dplyr::filter()
和is.finite()
或is.infinite()
范围变体的选项可能有用:
library(dplyr)
# sample data
df <- data_frame(a = c(1, 2, 3, NA), b = c(5, Inf, 8, 8), c = c(9, 10, Inf, 11), d = c('a', 'b', 'c', 'd'))
# across all columns:
df %>%
filter_all(all_vars(!is.infinite(.)))
# note that is.finite() does not work with NA or strings:
df %>%
filter_all(all_vars(is.finite(.)))
# checking only numeric columns:
df %>%
filter_if(~is.numeric(.), all_vars(!is.infinite(.)))
# checking only select columns, in this case a through c:
df %>%
filter_at(vars(a:c), all_vars(!is.infinite(.)))
is.finite
适用于vector
而不适用于data.frame
对象。 因此,我们可以遍历data.frame
使用lapply
,只得到“有限”的值。
lapply(df, function(x) x[is.finite(x)])
如果每列的Inf
、 -Inf
值的数量不同,则上面的代码将有一个元素length
不等的list
。 因此,最好将其保留为list
。 如果我们想要一个data.frame
,它应该具有相等的长度。
如果我们想删除包含任何 NA 或 Inf/-Inf 值的行
df[Reduce(`&`, lapply(df, function(x) !is.na(x) & is.finite(x))),]
或者@nicola的紧凑选项
df[Reduce(`&`, lapply(df, is.finite)),]
如果我们准备使用一个包,一个紧凑的选项是NaRV.omit
library(IDPmisc)
NaRV.omit(df)
set.seed(24)
df <- as.data.frame(matrix(sample(c(1:5, NA, -Inf, Inf),
20*5, replace=TRUE), ncol=5))
为了保持没有Inf
的行,我们可以这样做:
df[apply(df, 1, function(x) all(is.finite(x))), ]
也NA
由这个处理,因为:
值为NA
的 rowindex 将删除结果中的这一行。
带有NaN
行也不在结果中。
set.seed(24)
df <- as.data.frame(matrix(sample(c(0:9, NA, -Inf, Inf, NaN), 20*5, replace=TRUE), ncol=5))
df2 <- df[apply(df, 1, function(x) all(is.finite(x))), ]
以下是不同is.~
-functions 的结果:
x <- c(42, NA, NaN, Inf)
is.finite(x)
# [1] TRUE FALSE FALSE FALSE
is.na(x)
# [1] FALSE TRUE TRUE FALSE
is.nan(x)
# [1] FALSE FALSE TRUE FALSE
我遇到了这个问题,上述解决方案都不适合我。 我使用以下内容删除数据框第 15 和 16 列中带有 +/-Inf 的行。
d<-subset(c, c[,15:16]!="-Inf")
e<-subset(d, d[,15:16]!="Inf")
我花了一段时间为dplyr 1.0.0解决这个问题,所以我想我会使用c_across
来c_across
新版本的@sbha 解决方案,因为filter_all
, filter_if
已被弃用。
library(dplyr)
df <- tibble(a = c(1, 2, 3, NA), b = c(5, Inf, 8, 8), c = c(9, 10, Inf, 11), d = c('a', 'b', 'c', 'd'))
# a b c d
# <dbl> <dbl> <dbl> <chr>
# 1 1 5 9 a
# 2 2 Inf 10 b
# 3 3 8 Inf c
# 4 NA 8 11 d
df %>%
rowwise %>%
filter(!all(is.infinite(c_across(where(is.numeric)))))
# # A tibble: 4 x 4
# # Rowwise:
# a b c d
# <dbl> <dbl> <dbl> <chr>
# 1 1 5 9 a
# 2 2 Inf 10 b
# 3 3 8 Inf c
# 4 NA 8 11 d
df %>%
rowwise %>%
filter(!any(is.infinite(c_across(where(is.numeric)))))
# # A tibble: 2 x 4
# # Rowwise:
# a b c d
# <dbl> <dbl> <dbl> <chr>
# 1 1 5 9 a
# 2 NA 8 11 d
df %>%
rowwise %>%
filter(!any(is.infinite(c_across(a:c))))
# # A tibble: 2 x 4
# # Rowwise:
# a b c d
# <dbl> <dbl> <dbl> <chr>
# 1 1 5 9 a
# 2 NA 8 11 d
老实说,我认为@sbha 的答案更简单!
我认为自己是编码新手,我无法获得上述建议来处理我的代码。
我找到了一种不太复杂的方法来减少 2 行数据帧,首先用 Na 替换 Inf,然后选择具有完整数据的行:
Df[sapply(Df, is.infinite)] <- NA
Df<-Df[complete.cases(Df), ]
df[!is.infinite(df$x),]
其中 x 是包含无限值的 df 列。 发布的第一个答案取决于 rowsums 但对于我自己的问题,df 有无法添加的列。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.