r - 新的 dplyr 版本 1.0.6(或者可能更早)似乎滥用了 plyr 。dplyr中的点突变
问题描述
在我的 R 从 4.0 版更新到 4.1 版之前,我的以下代码运行良好,这是我为我正在开发的软件编写的辅助函数的一部分,我已经相应地替换了一些东西。没有上下文,这个功能似乎毫无意义,请不要专注于代码似乎试图在这里完成的事情。
input1 <- data.frame(a = as.numeric(c(0, NA, 0, 0, NA)),
b = as.factor(c("f", "f", NA, "f", NA)),
stringsAsFactors = FALSE)
input2 <- data.frame(a = as.numeric(1),
b = factor(c("m")),
c = factor(c("married")),
d = factor(c("AZ")),
e = as.character(0),
f = as.integer(59),
g = as.Date("2021-02-14"),
stringsAsFactors = FALSE
)
input2 <- input2 %>% dplyr::select( tidyselect::all_of( colnames(fake_data_) ) )
# error occurs here, in the second mutate
input1 %>%
dplyr::mutate(dplyr::across(.fns = as.character)) %>%
dplyr::mutate(dplyr::across( .cols = tidyselect::everything(),
.fns = ~eval(parse(text = paste0( "as.",
class( input2[[ dplyr::cur_column() ]]),
"(.)")))
))
我收到错误Error: Problem with `mutate()` input `..1`. i `..1 = dplyr::across(...)`. x 'list' object cannot be coerced to type 'double'
有人可以帮忙吗,在此先感谢!
解决方案
当谈到~
forpurrr
时,您可以看到它们是如何轻松工作的
library(rlang)
fun <- as_function(~.x + 1)
fun
#> <lambda>
#> function (..., .x = ..1, .y = ..2, . = ..1)
#> .x + 1
#> attr(,"class")
#> [1] "rlang_lambda_function" "function"
在这里我们看到它将创建一个函数,并将.x
'default 映射到第一个参数,.y
'default 映射到第二个参数,以及.
'default 到第一个参数。
您遇到的问题可能是由于dplyr
的评估掩码和对语言的计算。
您正在表达您的功能如下
fun2 <- as_function(~eval(parse(text = paste0( "as.",
class( input2[[ dplyr::cur_column() ]]),
"(.)"))))
并期望使用purrr
样式函数,但是实际发生的情况是,每次对列的调用都在评估之前将其表达式替换为列名。由于"(.)"
是一个字符,因此不会发生替换,而是尝试使用.
前缀 of magrittr
。
如果您执行以下操作,您可以了解正在发生的事情
input1 %>%
dplyr::mutate(dplyr::across(.fns = ~{browser(); as.character(.)}))
如果没有出现浏览器控件,n
请在控制台中键入以查看下一步,它应该显示为as.character(a)
,而不是as.character(.)
。
(注:输入Q
退出调试浏览器)
以下内容也应该产生您想要的结果:
input1 %>%
dplyr::mutate(dplyr::across(.fns = as.character)) %>%
dplyr::mutate(dplyr::across( .cols = tidyselect::everything(),
.fns = ~ do.call(paste0("as.",class(input2[[cur_column()]])), list(.))))
))
至于为什么在不同的版本中会出现这种情况,我不知道。我电脑上的 3.6.3 版产生的结果与 4.1 版相似。
推荐阅读
- embedded-linux - 我无法在启动期间导出 gpio 引脚
- c# - Moq - 抛出异步的函数设置不算作函数调用
- python - 如何根据多个其他列的条件为列分配值?
- c++ - C++ 内联汇编选择排序实现
- python - 如何在“x”个循环期间打印 number 的值?
- python-3.x - 如何在 aiohttp 服务器中自定义“不允许的方法”响应?
- javascript - 为什么我的交互收集器不收集?(discord.js)
- python - Python:对最喜欢的流派应用进行投票的问题
- python - geopy.exc.GeocoderServiceError:不成功的状态码 502
- cypress - 赛普拉斯 XHR 请求减慢几项测试