sparklyr中Join后过滤报错:无法解析number.x变量
解决Spark + dplyr连接后无法识别
number.x的问题 我之前在处理Spark和dplyr的连接操作时也碰到过一模一样的问题!其实根源在于dplyr自动生成的.x/.y列名后缀,在Spark SQL的执行上下文里不会被自动识别——毕竟这是dplyr自己的语法规则,而Spark原生SQL对带点的列名处理是有特殊要求的。
为什么会报错?
当你用inner_join连接两个存在重复列名的表时,dplyr会自动给来自左表的重复列加上.x后缀(右表则是.y),比如你的number.x。但Spark在解析底层SQL语句时,会把number.x当成“number表的x列”,而不是“number列的左表版本”,自然就找不到这个变量了。
两种快速解决办法
1. 提前给重复列重命名(最稳妥)
在连接之前就把左/右表的重复列改成独一无二的名字,彻底避免自动生成后缀的问题:
tbl(sc, 'dez') %>% # 给左表的number列重命名,避免后续自动加后缀 select(timefrom, elemuid, dez_number = number) %>% inner_join( tbl(sc, 'deg') %>% select(timefromdeg, elemuid, deg_number = number), by = c("timefrom" = "timefromdeg", "elemuid") ) %>% filter(dez_number > 2500) %>% glimpse()
2. 给表起别名,用别名引用列
通过alias()给表命名,然后直接用表别名来指定要过滤的列,Spark就能准确识别了:
# 给两个表分别起别名 dez_tbl <- tbl(sc, 'dez') %>% alias("dez") deg_tbl <- tbl(sc, 'deg') %>% alias("deg") dez_tbl %>% inner_join(deg_tbl, by = c("timefrom" = "timefromdeg", "elemuid")) %>% # 用表别名明确指定是左表的number列 filter(dez$number > 2500) %>% glimpse()
额外小提示
如果不想提前重命名所有列,也可以在过滤时用反引号把带点的列名包起来(不过这个方法有时候会因为dplyr的延迟执行规则失效,不如上面两种可靠):
tbl(sc, 'dez') %>% inner_join(tbl(sc, 'deg'), by = c("timefrom" = "timefromdeg", "elemuid")) %>% filter(`number.x` > 2500) %>% glimpse()
内容的提问来源于stack exchange,提问作者user60856839
相关产品推荐
相关产品推荐

