【问题标题】:How to split one SQL column into multiple columns in r如何在r中将一个SQL列拆分为多列
【发布时间】:2021-04-09 16:12:32
【问题描述】:

我在 R 中通过 dbplyr::memdb_frame() 创建了一个 tbl_SQLiteConnection 对象。

    library(dbplyr)
    library(dplyr)
    tb=memdb_frame(data.frame(ch=c('1a1','2a3'),cq=c(1,2)))
    tb

# Source:   table<dbplyr_002> [?? x 2]
# Database: sqlite 3.33.0 [:memory:]
  ch       cq
  <chr> <dbl>
1 1a1       1
2 2a3       2

我想将ch by a 拆分为两列:ch1ch2,如下所示:

# Source:   table<dbplyr_004> [?? x 3]
# Database: sqlite 3.33.0 [:memory:]
    ch1   ch2    cq
  <dbl> <dbl> <dbl>
1     1     1     1
2     2     3     2

我尝试这样的事情

sq <- paste0('SELECT split_part(ch,"a",1)
             FROM (',sql_render(tb),')')

tbl(tb$src$con,sql(sq))

没用!!!

您能帮我在 R 中如何进行吗?

【问题讨论】:

  • 你能添加你的预期输出吗
  • 谢谢!我已经添加了第一个答案

标签: sql r split dbplyr


【解决方案1】:

这行得通吗:

library(dplyr)
library(tidyr)
tb %>% separate(col = ch, into = c('ch1','ch2'), sep = 'a')
  ch1 ch2 cq
1   1   1  1
2   2   3  2

【讨论】:

  • 这个不行,这个命令对tibble很好用,但是在这里不行。 Error in UseMethod("separate") : no applicable method for 'separate' applied to an object of class "c('tbl_SQLiteConnection', 'tbl_dbi', 'tbl_sql', 'tbl_lazy', 'tbl')"
  • 试试tb %&gt;% collect() %&gt;% separate(...)?
  • 谢谢! collect() 与 as 相同。数据。 frame,不是sql,也是data。框架
【解决方案2】:

如果问题是如何使用 R 中的 SQLite 选择语句将数据框中的指定列分成两部分,则以下选择语句使用 SQLite 的 instrsubstr 函数。

library(sqldf)

tb <- data.frame(ch = c('1a1', '2a3'), cq = c(1, 2))

sqldf("
  select 
    substr(ch, 1, instr(ch, 'a') - 1) as ch1,
    substr(ch, instr(ch, 'a') + 1) as ch2,
    cq
  from tb")

给予:

  ch1 ch2 cq
1   1   1  1
2   2   3  2

【讨论】:

  • 问题是如何拆分一个SQL列,而不是按SQL语法拆分一个数据框列。
【解决方案3】:

基于我对this question 的回答,这里有两种方法。两者都假设您不知道拆分字符(在本例中为 'a')在字符串中的哪个位置,因此这是第一步。如果您的拆分字符始终位于同一位置(例如,它始终是字符串中的第二个字符,如上例所示),您可以简化该方法。

基于 SQL 的

我们可以按照问题中的方法编写一个 SQL 查询并将其传递给表定义:

query = paste0("
SELECT ch, cq, split_index
    ,SUBSTRING(ch, 1, split_index - 1) AS ch1
    ,SUBSTRING(ch, split_index + 1, LEN(ch)) AS ch2
FROM (

SELECT ch, cq, CHARINDEX('a', ch) AS split_index
FROM ", sql_render(input_tbl), "

) AS subquery"

tbl(input_tbl$src$con, sql(query))

请注意,不同风格的 SQL 可能对 SUBSTRINGCHARINDEXLEN 函数有不同的名称。这些函数也可以采用不同的参数(例如子字符串的长度或子字符串结尾的索引)。您需要确保拥有适合您的 SQL 风格的正确函数。

基于 dbplyr

dbplyr 可以将一些标准的 R 和 dplyr 命令翻译成 SQL。这使您可以编写 R 并将其自动转换为 SQL。

lubrary(dbplyr)
library(stringr)

input_tbl %>%
  mutate(split_index = str_locate('a', ch) %>%
  mutate(ch1 = substr(ch, 1, split_index - 1),
         ch2 = substr(ch, split_index + 1, nchar(ch)))

注意:str_locate 查找拆分字符的索引。在我的测试中,并不是每种 SQL 都为此定义了翻译。因此,根据您的数据库,这种方法可能会失败。

但是,您可以直接使用等效的 SQL 函数。因为 dbplyr 没有为它定义翻译,所以函数应该未经翻译地传递给服务器。

例如,在 SQL 服务器中,CHARINDEXstr_locate 具有相同的用途。因此,您可以使用CHARINDEX('a', ch) 而不是str_locate('a', ch)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 2014-07-28
    • 2022-12-05
    相关资源
    最近更新 更多