首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R dbplyr mysql列转换

R dbplyr mysql列转换
EN

Stack Overflow用户
提问于 2021-08-27 14:05:33
回答 2查看 34关注 0票数 0

我在mySQL中有一个表,它看起来像这样:

代码语言:javascript
复制
tbl<-tibble(
   Result=c("0.1","<0.0001","1.1"),
   Unit=c("mg/L","ug/L","mg/L"),
   Pref_Unit=c("mg/L","mg/L","mg/L"),
   Conversion=c(1,1000,1)
)

我想使用dbplyrpoolRMariaDB执行的操作是使用表中的转换因子将Result列转换为首选单位,同时保留"<",并将结果列拆分为只包含数字和numeric分数的censored,以指示Result是否包含"<“。

对于常规的dplyr,我会这样做:

代码语言:javascript
复制
tbl<-tbl %>%
    mutate(numb_Result=as.numeric(gsub("<","",Result)),
           cen_Result=grepl("<",Result)) %>%
    mutate(new_Result=ifelse(cen_Result,paste0("<",numb_Result*Conversion),paste0(numb_Result*Conversion)))

但这不适用于数据库表。任何帮助都将不胜感激。

EN

回答 2

Stack Overflow用户

发布于 2021-08-29 09:54:20

挑战很可能是因为dbplyr没有为gsubgrepl定义转换。下面是你可以测试的几种可能性:

代码语言:javascript
复制
library(dplyr)
library(dbplyr)

tbl<-tibble(
  Result=c("0.1","<0.0001","1.1"),
  Unit=c("mg/L","ug/L","mg/L"),
  Pref_Unit=c("mg/L","mg/L","mg/L"),
  Conversion=c(1,1000,1)
)

remote_table = tbl_lazy(tbl, con = simulate_mssql())

remote_table %>%
  mutate(has_sign = ifelse(substr(Result, 1, 1) == "<", 1, 0)) %>%
  mutate(removed_sign = ifelse(has_sign == 1, substr(Result, 2, nchar(Result)), Result)) %>%
  mutate(num_value = as.numeric(removed_sign)) %>%
  mutate(converted = as.character(1.0 * num_value * Conversion)) %>%
  mutate(new_Result = ifelse(has_sign, paste0("<",converted), converted))

有针对ifelsesubstrncharas.numericas.characterpaste0的dbplyr转换。所以我希望这能行得通。但是,我一直收到一个错误,因为转换器要求substrstartstop参数必须是常量,因此它不喜欢我将nchar(Results)作为参数传递。但这可能会在较新版本的包中修复。

我第二次尝试:

代码语言:javascript
复制
remote_table %>%
  mutate(has_sign = ifelse(substr(Result, 1, 1) == "<", 1, 0),
         character_length = nchar(Result),
         remove_first = sql(REPLACE(Result, "<", ""))) %>%
  mutate(removed_sign = ifelse(has_sign == 1, remove_first, Result)) %>%
  mutate(num_value = as.numeric(removed_sign)) %>%
  mutate(converted = as.character(1.0 * num_value * Conversion)) %>%
  mutate(new_Result = ifelse(has_sign, paste0("<",converted), converted))

这将产生预期的SQL转换。但是,由于我使用的是模拟的数据库连接,因此无法测试它是否返回预期的输出。这种方法的缺点是它直接使用SQL函数REPLACE (它传递未经翻译的SQL代码),这不如完全翻译的解决方案优雅。

可能有更优雅的方法来做到这一点。但希望在这两者之间你能找到一个合适的解决方案。

票数 0
EN

Stack Overflow用户

发布于 2021-08-31 12:40:07

谢谢你,西蒙!

我已经找到了一个类似的解决方案,它在实际的SQL数据库环境中工作(注意,我还必须将列名作为变量result_col传递,因此使用!!sym()):

代码语言:javascript
复制
tbl %>%
mutate(numb_res = REGEXP_REPLACE(!!sym(result_col),"<",""), 
       cen_res = !!sym(result_col) %like% "<%") %>%
      mutate(numb_res=numb_res*Conversion) %>%
      mutate(!!result_col:=case_when(
        cen_res==1 ~ paste0("<",numb_res),
        T ~ paste0(numb_res)
      ))

看起来您是对的,as.character()as.numeric()没有SQL转换,但只需对字符向量进行乘法就足以使其成为数字,类似地,粘贴带有"<“的值就可以使其返回到字符中。

我认为这对我是有效的,但我也会调查你的答案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68954791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档