我有一个非常大的数据帧( 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)中的错误:未对类型实现默认方法 '列表'
EDITED
删除整行,即使相应的一列或多列都有inf和-inf
答案 0 :(得分:21)
要删除+/- Inf
行,我建议如下:
df <- df[!is.infinite(rowSums(df)),]
或等同地
df <- df[is.finite(rowSums(df)),]
第二个选项(具有is.finite()
且没有否定的选项)也会删除包含NA
值的行,以防尚未执行此操作。
答案 1 :(得分:8)
is.finite
适用于vector
而非data.frame
对象。因此,我们可以使用data.frame
遍历lapply
并仅获取有限的&#39;值。
lapply(df, function(x) x[is.finite(x)])
如果每列的Inf
,-Inf
值不同,则上述代码的list
元素的元素不等length
。因此,最好将其保留为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))
答案 2 :(得分:4)
要保留没有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.~
- 函数的结果:
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
答案 3 :(得分:2)
根据数据,有一些使用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(.)))
答案 4 :(得分:1)
我认为自己是编码新手,无法获得上述建议来处理我的代码。
我找到了一种不太复杂的方法来减少 2 行数据帧,首先用 Na 替换 Inf,然后选择具有完整数据的行:
Df[sapply(Df, is.infinite)] <- NA
Df<-Df[complete.cases(Df), ]
答案 5 :(得分:1)
df[!is.infinite(df$x),]
其中 x 是包含无限值的 df 列。发布的第一个答案取决于 rowsums,但对于我自己的问题,df 有无法添加的列。
答案 6 :(得分:0)
我遇到了这个问题,上述解决方案都无法解决。我使用以下内容删除了数据框第15列和第16列中带有+/- Inf的行。
d<-subset(c, c[,15:16]!="-Inf")
e<-subset(d, d[,15:16]!="Inf")
答案 7 :(得分:0)
我花了一段时间为 dplyr 1.0.0 进行了研究,所以我认为自c_across
起,我将使用filter_all
提出新版本的@sbha解决方案, 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的答案更简单!