【问题标题】:Different results from dplyr filter starting with identical data从相同数据开始的 dplyr 过滤器的不同结果
【发布时间】:2015-03-12 14:08:40
【问题描述】:

当我试图回答this question 时,我遇到了一些非常奇怪的行为。下面我定义了两次相同的数据,一次是data.frame,第二次使用mutate。我检查结果是否相同。然后我尝试做同样的过滤操作。对于第一个数据集,这是可行的,但对于第二个(相同的)数据集,它会失败。任何人都可以弄清楚为什么。

似乎造成这种差异的部分原因是使用了ñ。但我不明白为什么这对第二个数据集来说是个问题,而不是对第一个数据集。

# define the same data twice
datos1 <- data.frame(año = 2001:2005, gedad = c(letters[1:5]), año2 = 2001:2005)  
datos2 <- data.frame(año = 2001:2005, gedad = c(letters[1:5])) %>% mutate(año2 = año) 
# check that they are identical
identical(datos1, datos2)
# do same operation
datos1 %>% filter(año2 >= 2003)
## año gedad año2
## 1 2003     c 2003
## 2 2004     d 2004
## 3 2005     e 2005
datos2 %>% filter(año2 >= 2003)
## Error in filter_impl(.data, dots) : object 'año2' not found

注意:我不认为这是原始问题的重复,因为我问为什么会出现这种差异,而原始帖子询问如何解决它。

编辑:由于@Khashaa 无法重现错误,这是我的sessionInfo() 输出:

sessionInfo()
## R version 3.1.2 (2014-10-31)
## Platform: x86_64-w64-mingw32/x64 (64-bit)
## 
## locale:
## [1] LC_COLLATE=German_Switzerland.1252  LC_CTYPE=German_Switzerland.1252    LC_MONETARY=German_Switzerland.1252
## [4] LC_NUMERIC=C                        LC_TIME=German_Switzerland.1252    
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] dplyr_0.4.1
## 
## loaded via a namespace (and not attached):
## [1] assertthat_0.1  DBI_0.3.1       lazyeval_0.1.10 magrittr_1.5    parallel_3.1.2  Rcpp_0.11.4     tools_3.1.2  

【问题讨论】:

  • 无法重现错误。
  • 就是这样。它使用机器的系统语言环境,将ñ 翻译成其他字符。在这种情况下,字符可能看起来相同,但我敢打赌它具有不同的 ASCII 值。在我的希腊机器中,我在错误消息中得到ρ 而不是ñ。我可以使用datos2 %&gt;% filter("aρo2" &gt;= 2003) 进行查询
  • 我怀疑机器的代码页是 850 或类似的东西,它使用与 Windows 1252 或 437 不同的变音符号位置
  • 我明白为什么它们看起来一样,但内部表示不同。但是为什么identical 没有发现差异呢?那么为什么datos2 %&gt;% subset(año2&gt;=2003) 会起作用呢?
  • 现在就做——尽管在 R 决定像其他人一样使用 Unicode 之前不要使用非英文字符

标签: r dplyr


【解决方案1】:

通过将 R 的语言环境切换为German_Switzerland.1252,我能够在具有希腊系统语言环境的机器上重现该错误。我还注意到,在第二种情况下,错误和变量的名称​​已更改aρo2

mutate 似乎在创建新列的名称时使用了系统语言环境,如果这与控制台使用的语言环境不同,则会导致转换。我能够使用修改后的列名查询dato2

library(dplyr)
Sys.setlocale("LC_ALL","German_Switzerland.1252")
datos1 <- data.frame(año = 2001:2005, gedad = c(letters[1:5]), año2 = 2001:2005)  
datos2 <- data.frame(año = 2001:2005, gedad = c(letters[1:5])) %>% mutate(año2 = año) 

datos1 %>% filter(año2 >= 2003)
##   aρo gedad aρo2
## 1 2003     c 2003
## 2 2004     d 2004
## 3 2005     e 2005
datos2 %>% filter(año2 >= 2003)
##  Error in filter_impl(.data, dots) : object 'aρo2' not found
datos2 %>% filter("aρo2" >= 2003)
## aρo gedad aρo2
## 1 2001     a 2001
## 2 2002     b 2002
## 3 2003     c 2003
## 4 2004     d 2004
## 5 2005     e 2005

ñ 在原问题中出现在这两种情况下的原因可能意味着机器的系统区域设置为 850,这是一个拉丁代码页,其中带有变音符号的字符的代码与 Windows 1252 不同。

“有趣”的是:

names(datos2)[[1]]==names(datos1)[[1]]
## [1] TRUE

因为

names(datos1)[[1]]
## [1] "aρo"

names(datos2)[[1]]
## [1] "aρo"

这意味着 R 本身会进行混乱的转换,而其 filter 会进行正确的转换。

所有这一切的士气是 - 不要使用非英文字符,或确保使用与机器相同的语言环境(相当脆弱)。

更新

Semi-official confirmation R 确实经过系统区域设置,因为它假定它实际上 系统使用的区域设置。虽然 Windows 始终使用 UTF-16,但“系统区域设置”实际上是“区域设置”框中的标签所说的 - 用于旧版非 Unicode 应用程序的区域设置。

如果我没记错的话,在 Windows 2000 和 NT 之前,“系统区域设置”曾经是整个系统的区域设置(包括 UI 语言等)。如今,您甚至可以为每个用户使用不同的 UI 语言,但名称已经卡住了。

【讨论】:

  • 找出names(datos1)names(datos2) 不同的一种方法是检查它们的编码。 Encoding(names(datos2)) 返回“UTF-8”而不是“未知”
  • 实际上,它返回"unknown" "unknown" "unknown"为dato1和"unknown" "unknown" "UTF-8" 为dato2。然而,通过aρo2 可以进行过滤。将代码页设置为 65001 可以解决此问题,但 R 不接受 10000 以上的所有代码页。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-08
  • 1970-01-01
  • 2021-10-12
  • 1970-01-01
  • 2014-07-06
  • 2015-08-28
相关资源
最近更新 更多