R子集/过滤器不返回任何行

时间:2018-04-05 02:34:18

标签: r dplyr subset

对不起,这是一个太微不足道的问题,但是:

无论是dplyr还是基础R,都不可能根据行的总和进行过滤/子集,尽管它具有相同的类和类型。在一个全数字列数据框中,我可以按每个整数(例如1)对每个列进行子集,但是那个包含rowums。

library(dplyr)

x <- seq(-1, 1, 0.2)


#With dplyr

df <- data.frame(V1 = x, V2 = x, V3 = x, V4 = x, V5 = x)

df <- df %>% mutate(soma = rowSums(df))

df %>% filter(V1 == V2, V2==V3, V3 == V4, V4 == V5) #Works!

df %>% filter(V1 == 1) #Works!

df %>% filter(soma == 1) #Why this filter does not work?

class(df$V1)

class(df$soma)

typeof(df$V1)

typeof(df$soma)


#R base

df <- data.frame(V1 = x, V2 = x, V3 = x, V4 = x, V5 = x)

df$soma <- rowSums(df)

df[with(df, V1 == V2, V2==V3, V3 == V4, V4 == V5),] #Works!

df[df$V1 == 1,] #Works!

df[df$soma == 1,] #Why this filter does not work?

class(df$V1)

class(df$soma)

typeof(df$V1)

typeof(df$soma)

3 个答案:

答案 0 :(得分:2)

Floats are inaccurate;你不能期望比较浮点数,因为数学证明,特别是如果它们来自计算,这会导致舍入错误。

您需要指定一些容差来比较浮点数以获得合理的结果。

df %>% filter(abs(soma - 1) < 0.00000000001)

#   V1  V2  V3  V4  V5 soma
#1 0.2 0.2 0.2 0.2 0.2    1

答案 1 :(得分:1)

如果您输入以下内容,您会发现soma中的第7个号码不等于1

print(df$soma[7], digit = 21)
[1] 1.0000000000000009

请参阅此链接,详细了解原因:Why are these numbers not equal?

解决此问题的一种方法是在过滤之前使用round函数。

df %>%
  mutate(soma2 = round(soma)) %>%
  filter(soma2 == 1)
   V1  V2  V3  V4  V5 soma soma2
1 0.2 0.2 0.2 0.2 0.2    1     1

答案 2 :(得分:0)

这是一个机器舍入错误问题。看看

df %>% filter(abs(soma - 1) < 0.000001)

你的号码被保存为双打,所以他们有一些四舍五入。将数字保存为整数(在1L之后添加L,转换它们,或在计算中允许机器舍入错误(如上所述)。