首页 > 解决方案 > 代码独立工作,但不是函数

问题描述

我有一个功能,我为一个不再工作的包制作了一个功能,我无法弄清楚为什么。该函数的重点是将一串十六进制数据转换为数据框(链接到 github 上的示例)。这段代码很长,所以这里没有全部包含,这里是github 上代码的链接。当我逐行运行代码时,它运行良好,但是当我尝试使用该函数时,我得到了这个:

> sample1.df <- transformssd(hex_data = sample1)
a: 1.08641362190247
a: 59.1739654541016
a: 0.32277500629425
a: 2.70198535919189
a: 0.127873212099075
a: 0.262394219636917
a: 27.9828720092773
a: 0.140874609351158
a: 0.274696856737137
a: 0.336845397949219
a: 0.452615290880203
a: 0.107537969946861
a: 0.12063916772604
a: 0.198753878474236
a: 0.521674871444702
a: 0.863220930099487
a: 0.765538036823273
Error: Must subset columns with a valid subscript vector.
x Can't convert from <double> to <integer> due to loss of precision.

此处显示的值是我想要在我的数据框中获取的值,因此创建数据框似乎是问题所在。运行时rlang::last_error()rlang::last_trace()这就是我得到的:

> rlang::last_error()
x
+-<error/vctrs_error_subscript_type>
| Must subset columns with a valid subscript vector.
| x Can't convert from <double> to <integer> due to loss of precision.
\-<error/vctrs_error_cast_lossy>
  Can't convert from <double> to <integer> due to loss of precision.
Backtrace:
  1. xrfr::transformssd(hex_data = sample1)
 22. vctrs:::try_catch_impl(...)
 27. vctrs:::try_catch_callback(data, NULL)
 29. vctrs:::vec_cast.integer.double(...)
 30. vctrs::maybe_lossy_cast(out, x, to, lossy, x_arg = x_arg, to_arg = to_arg)
 34. vctrs:::stop_lossy_cast(...)
 35. vctrs:::stop_vctrs(...)

> rlang::last_trace()
x
+-<error/vctrs_error_subscript_type>
| Must subset columns with a valid subscript vector.
| x Can't convert from <double> to <integer> due to loss of precision.
\-<error/vctrs_error_cast_lossy>
  Can't convert from <double> to <integer> due to loss of precision.
Backtrace:
     x
  1. +-xrfr::transformssd(hex_data = sample1)
  2. | \-values.df %>% dplyr::select(a)
  3. +-dplyr::select(., a)
  4. +-dplyr:::select.data.frame(., a)
  5. | \-tidyselect::eval_select(expr(c(...)), .data)
  6. |   \-tidyselect:::eval_select_impl(...)
  7. |     +-tidyselect:::with_subscript_errors(...)
  8. |     | +-base::tryCatch(...)
  9. |     | | \-base:::tryCatchList(expr, classes, parentenv, handlers)
 10. |     | |   \-base:::tryCatchOne(expr, names, parentenv, handlers[[1L]])
 11. |     | |     \-base:::doTryCatch(return(expr), name, parentenv, handler)
 12. |     | \-tidyselect:::instrument_base_errors(expr)
 13. |     |   \-base::withCallingHandlers(...)
 14. |     \-tidyselect:::vars_select_eval(...)
 15. |       \-tidyselect:::walk_data_tree(expr, data_mask, context_mask)
 16. |         \-tidyselect:::eval_c(expr, data_mask, context_mask)
 17. |           \-tidyselect:::reduce_sels(node, data_mask, context_mask, init = init)
 18. |             \-tidyselect:::walk_data_tree(new, data_mask, context_mask)
 19. |               \-tidyselect:::as_indices_sel_impl(...)
 20. |                 \-tidyselect:::as_indices_impl(x, vars, strict = strict)
 21. |                   \-vctrs::vec_as_subscript(x, logical = "error")
 22. \-vctrs:::try_catch_impl(...)
 23.   +-base::tryCatch(try_catch_callback(data, NULL), ...)
 24.   | \-base:::tryCatchList(expr, classes, parentenv, handlers)
 25.   |   \-base:::tryCatchOne(expr, names, parentenv, handlers[[1L]])
 26.   |     \-base:::doTryCatch(return(expr), name, parentenv, handler)
 27.   \-vctrs:::try_catch_callback(data, NULL)
 28.     \-(function () ...
 29.       \-vctrs:::vec_cast.integer.double(...)
 30.         \-vctrs::maybe_lossy_cast(out, x, to, lossy, x_arg = x_arg, to_arg = to_arg)
 31.           +-base::withRestarts(...)
 32.           | \-base:::withOneRestart(expr, restarts[[1L]])
 33.           |   \-base:::doWithOneRestart(return(expr), restart)
 34.           \-vctrs:::stop_lossy_cast(...)
 35.             \-vctrs:::stop_vctrs(...)

看起来问题出在dplyr::select()某种程度上,但我一直无法弄清楚原因。如果有人能帮我解决这个问题,我将不胜感激,谢谢!

上面链接的十六进制数据可用于测试代码。

编辑

到目前为止,我无法在更短的函数中重现错误,但是这段代码并没有创建它应该创建的数据框。由于最初的问题是创建数据框,我认为这可能仍然有助于解决问题。

library(tidyverse)
library(magicfor)

subhex <- c("9A0F8B3F", "24B26C42", "C442A53E")

transformhex <- function(hex_string) {
  subhex <- hex_string
  magic_for(silent = TRUE)
  for (i in 1: length(subhex)) {
    a <- readBin(as.raw(strtoi(apply(matrix(strsplit(subhex,"")[[i]],2),2,paste, collapse=""), 16)), "double", size=4)
    put(a)
  }
  
  values1.df <- magic_result_as_dataframe()
  values1.df <- values1.df %>% 
    dplyr::select(a)
  
  return(values1.df)
}

> transformhex(hex_string = subhex)
          a
1  1.086414
2 59.173965
3  0.322775

与原始函数一样,它显示正确的值,但不创建数据框。和以前一样,这只是使用函数时的问题,而不是逐行运行代码时的问题。

标签: rfunctiondplyrr-package

解决方案


万一其他人将来遇到这个问题,我将分享对我有用的解决方案:

我的问题是在magicfor我的函数中使用包中的函数。多亏了另一个问题的回答,我才能够更改for循环以使其正常工作:

values.df <- data.frame()

  for (i in 1:length(subsubsplit1)) {
    a <- readBin(as.raw(strtoi(apply(matrix(strsplit(subsubsplit1,"")[[i]],2),2,paste, collapse=""), 16)), "double", size=4)
    values.df <- rbind(values.df, data.frame(t(a), row.names = NULL))
  }

  colnames(values.df) <- "kcps"

推荐阅读