【问题标题】:Help on subsetting a dataframe帮助子集数据框
【发布时间】:2011-08-09 14:58:32
【问题描述】:

我正在使用 %in% 进行子集化,但遇到了一个奇怪的结果。

> my.data[my.data$V3 %in% seq(200,210,.01),]
        V1     V2        V3         V4       V5      V6         V7
56     470   48.7    209.73        yes     26.3      54        470

那是正确的。但是当我扩大范围时……第 56 行就消失了

> my.data[my.data$V3 %in% seq(150,210,.01),]
        V1     V2        V3         V4       V5      V6         V7
51     458   48.7    156.19        yes     28.2      58        458
67     511   30.5    150.54        yes     26.1      86        511
73     535   40.6    178.76        yes     29.5      73        535

你能告诉我有什么问题吗? 有没有更好的方法来对数据框进行子集化?

这是它的结构

> str(my.data)
'data.frame':   91 obs. of  7 variables:
 $ V1: Factor w/ 91 levels "100","10004",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ V2: num  44.6 22.3 30.4 38.6 15.2 18.3 16.3 12.2 36.7 12.2 ...
 $ V3: num  110.83 25.03 17.17 57.23 2.18 ...
 $ V4: Factor w/ 2 levels "no","yes": 1 2 2 2 1 1 1 1 1 1 ...
 $ V5: num  22.3 30.5 24.4 25.5 4.1 28.4 7.9 5.1 24 12.2 ...
 $ V6: int  50 137 80 66 27 155 48 42 65 100 ...
 $ V7: chr  "" "10004" "10005" "10012" ...

【问题讨论】:

  • 您能否澄清您是要返回V3 在规定范围内的所有行,还是只想返回等于您打算返回的序列号的行?
  • 鉴于 V3 被四舍五入为 2 位十进制数字,我认为“V3 在规定范围内的所有行”与“等于增量为 . 01”。为了回答你的问题,我想要第一个
  • V3 可能是准确的,我不知道所有的值。问题是seq() 的值不是四舍五入的、精确的,这就是问题所在。无论如何,通过测试精确相等来做事注定要在使用浮点运算的计算机上失败。在 R 中使用小于和大于运算符更安全/更容易/正确。请参阅我的答案或@nullglob 的答案的第二个选项(尽管忽略他的第一个选项,因为那是错误的)。

标签: r dataframe subset


【解决方案1】:

哎呀。您正在尝试在无法准确表示所有数字的计算机上进行精确匹配。

> any(209.73 == seq(200,210,.01))
[1] TRUE
> any(209.73 == seq(150,210,.01))
[1] FALSE
> any(209.73 == zapsmall(seq(150,210,.01)))
[1] TRUE

差异的原因在于第二个序列,序列中的值正好是209.73。这是您在使用计算机进行计算时必须意识到的。

这在互联网上的许多地方都有介绍,但关于 R,请参阅 R 常见问题解答中的 point 7.31

无论如何,也就是说,您解决问题的方法不正确。您想使用正确的数字运算符:

my.data[my.data$V3 >= 150 & my.data$V3 <= 210, ]
## or
subset(my.data, V3 >= 150 & V3 <= 210)

【讨论】:

    猜你喜欢
    • 2014-02-14
    • 2010-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-04
    相关资源
    最近更新 更多