【问题标题】:sqldf R code that renames variables based on a pattern基于模式重命名变量的 sqldf R 代码
【发布时间】:2020-03-06 01:17:48
【问题描述】:

我有一个包含 50,000 多行不同名称的 csv 格式的列表,下面有相同的 5 位代码:

Code             Name
25000            James John Junior
RA25000          James Junior
RA2500009        James J. Junior
RA27000          Bill Hope
RA2800009        Donna Scott
28000            Donna Love Scott

由于列表共享相同的底层代码,例如 25000,我如何使用 R 中的 sqldf 包(如下所示)更改列表以使其名称与底层代码相关联(例如 25000)。仅使用 Rstudio。

Code             Name
25000            James John Junior
RA25000          James John Junior
RA2500009        James John Junior
RA27000          Bill Hope
RA2800009        Donna Love Scott
28000            Donna Love Scott

注意,我想避免在代码中分别输入 25000、27000、28000,因为列表本身有超过 50,000 行,并且可能有 40,000 种基础代码变体。

【问题讨论】:

    标签: sql r list sqldf


    【解决方案1】:

    假设您的sqldf 版本支持common table expressions(SQLite 3.8.3+),请考虑使用SUBSTRREPLACE 清理代码,并将其加入聚合CTE 以对齐最大长度的名称。 CTE 的最终自连接需要映射干净的名称。

    WITH agg AS
       (SELECT SUBSTR(REPLACE([Code], 'RA', ''),1,5) AS CleanCode, 
               MAX(LENGTH([Name])) AS MaxLenName
        FROM myData
        GROUP BY SUBSTR(REPLACE([Code], 'RA', ''),1,5)
       ),
       sub AS 
       (SELECT SUBSTR(REPLACE([Code], 'RA', ''),1,5) AS CleanCode, 
               LENGTH([Name]) AS LenName,
               [Code],
               [Name]
        FROM myData
       )
    
    SELECT sub.Code,
           sub2.Name
    FROM sub
    INNER JOIN agg
       ON agg.CleanCode = sub.CleanCode
    LEFT JOIN sub as sub2
       ON agg.CleanCode = sub2.CleanCode
       AND agg.MaxLenName = sub2.LenName;
    

    Online Demo (点击顶部运行)

    | Code      | Name              |
    | --------- | ----------------- |
    | 25000     | James John Junior |
    | RA25000   | James John Junior |
    | RA2500009 | James John Junior |
    | RA27000   | Bill Hope         |
    | RA2800009 | Donna Love Scott  |
    | 28000     | Donna Love Scott  |
    

    【讨论】:

    • 这可以在 R 环境 (RStudio) 中使用 sqldf 包完成吗?因为我觉得我的sqldf版本不支持公用表表达式
    • 尝试升级RSQLitesqldf的依赖):install.packages("RSQLite")
    • 另外,您收到的具体错误是什么?请务必将查询用双引号(不是单引号)括起来,并将 mydata 替换为您的数据框名称。
    【解决方案2】:

    使用在最后的注释中重复显示的输入执行左自连接。 ltrim 删除DF 的第一个实例的代码左侧的任何AR,然后substr 采用接下来的5 个字符。将其与DFCode 的第二个实例匹配。如果数字前面可以有其他字母,请将它们包含在AR 字符串中。如果可以出现任何大写字母,则使用ABCDEFGHIJKLMNOPQRSTUVWXYZ

    library(sqldf)
    sqldf("select a.Code, coalesce(b.Name, a.Name) Name 
      from DF a left join DF b
      on substr(ltrim(a.Code, 'AR'), 1, 5) = b.Code")
    

    给予:

           Code              Name
    1     25000 James John Junior
    2   RA25000 James John Junior
    3 RA2500009 James John Junior
    4   RA27000         Bill Hope
    5 RA2800009  Donna Love Scott
    6     28000  Donna Love Scott
    

    注意

    Lines <- "Code             Name
    25000            James John Junior
    RA25000          James Junior
    RA2500009        James J. Junior
    RA27000          Bill Hope
    RA2800009        Donna Scott
    28000            Donna Love Scott"
    Lines2 <- readLines(textConnection(Lines))
    DF <- read.csv(text = sub(" +", ",", Lines2), header = TRUE, strip.white = TRUE)
    

    【讨论】:

    • 我知道 a.Code 是代码列,b.Code 是正在创建的新列,但是 a.Name 和 b.Name 指的是什么?
    • DF 有两个实例,a 和 b,它们都是相同的,即它们都有 Code 和 Name 列。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-19
    • 2022-01-05
    • 2017-03-16
    • 2013-03-25
    • 2020-06-16
    • 2015-03-11
    • 1970-01-01
    相关资源
    最近更新 更多