繁体   English   中英

如何从 R 中的数据框中删除带有 inf 的行

[英]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_acrossc_across新版本的@sbha 解决方案,因为filter_allfilter_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM