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

Eka*_*Eka 25 r dataframe

我有一个非常大的数据帧(DF)用约35-45列(变量)和行大于300行的一些包含NA,NaN时,天道酬勤,在单个或多个变量值-Inf和我已经使用 na.omit(df)以除去行使用NA和NaN但我无法使用na.omit函数删除具有Inf和-Inf值的行.

在搜索时,我遇到了这个线程在R中删除了带有Inf和NaN的行并使用了修改后的代码,df[is.finite(df)]但它没有删除带有Inf和-Inf的行,并且也给出了这个错误

is.finite(df)出错:未对类型'list'实现默认方法

EDITED

即使相应的一列或多列具有inf和-inf,也要删除整行

RHe*_*tel 27

要用+/-删除行,Inf我建议如下:

df <- df[!is.infinite(rowSums(df)),]
Run Code Online (Sandbox Code Playgroud)

或者,等效地,

df <- df[is.finite(rowSums(df)),]
Run Code Online (Sandbox Code Playgroud)

第二个选项(带有is.finite()和不带有否定的选项)也会删除包含NA值的行,以防尚未执行此操作.


sbh*_*bha 15

根据数据,有几个选项使用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(.)))
Run Code Online (Sandbox Code Playgroud)


akr*_*run 10

对象的is.finite作用,vector而不是data.frame对象的作品.因此,我们可以遍历data.frame使用lapply并获得"有限"值.

lapply(df, function(x) x[is.finite(x)])
Run Code Online (Sandbox Code Playgroud)

如果数量Inf,-Inf为每列值是不同的,上面的代码将具有list与具有不相等的元件length.因此,最好将其留作list.如果我们想要一个data.frame,它应该有相同的长度.


如果我们要删除包含任何NA或Inf/-Inf值的行

df[Reduce(`&`, lapply(df, function(x) !is.na(x)  & is.finite(x))),]
Run Code Online (Sandbox Code Playgroud)

或@nicola的紧凑选项

df[Reduce(`&`, lapply(df, is.finite)),]
Run Code Online (Sandbox Code Playgroud)

如果我们准备使用包,那么紧凑的选项就是 NaRV.omit

library(IDPmisc)
NaRV.omit(df)
Run Code Online (Sandbox Code Playgroud)

数据

set.seed(24)
df <- as.data.frame(matrix(sample(c(1:5, NA, -Inf, Inf), 
                      20*5, replace=TRUE), ncol=5))
Run Code Online (Sandbox Code Playgroud)


use*_*230 5

我花了一段时间才为dplyr 1.0.0解决这个问题,所以我想我会使用新版本的 @sbha 解决方案c_across,因为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 
Run Code Online (Sandbox Code Playgroud)

说实话,我认为@sbha 的答案更简单!