R语言filter函数过滤数值列结果异常的原因咨询
问题根因
你的过滤逻辑错误是比较时混用了数值和字符串类型,触发了字符串字典序比较规则,没有按数值大小判断。
从你贴的输出可以看到row_number是<dbl>(双精度数值)类型,但你写的过滤条件row_number < '13'里,右侧的'13'是带单引号的字符串值。R遇到跨类型比较时会自动做类型转换,这里实际是把所有row_number的数值转成字符串后,按字典序逐位比较字符顺序,和数值大小的判断逻辑完全不一样:
- 字符串比较规则是从左到右逐位对比字符的编码值,只要某一位分出大小就直接返回结果,不会看整体数值:
- 值为1、10、11、12的记录转成字符串是
'1'、'10'、'11'、'12',第一位都是字符'1',和'13'的第一位相等,再比第二位:'1'没有第二位、'0'/'1'/'2'的编码都小于'3',所以被判定为「小于'13'」保留了下来。 - 值为2~9的记录转成字符串是
'2'到'9',第一位字符的编码都大于'13'的第一位'1',直接被判定为「大于'13'」,全被过滤掉了。 - 20、21、22转成字符串第一位是
'2',同样大于'1',也被过滤,最终就只剩你看到的4个取值。
- 值为1、10、11、12的记录转成字符串是
修正方案
去掉比较值的引号,用纯数值做比较,让逻辑按数值大小执行即可:
dat1 <- dat1 %>% filter(row_number < 13)
如果不确定row_number列的类型会不会被意外转成字符,也可以显式做类型转换,兼容性更好:
dat1 <- dat1 %>% filter(as.numeric(row_number) < 13)
注意事项
做数值比较、算术运算时,一定要确认参与计算的值都是数值类型,不要给数值随意加引号变成字符串。字符串排序和数值排序逻辑差异极大,比如字符串比较下'100' < '2'的返回结果是TRUE,和数值逻辑完全相反,非常容易出现类似的逻辑错误。
内容的提问来源于stack exchange,提问作者Kinsley
相关产品推荐
相关产品推荐

