我以不同的名称以csv格式列出了50,000多行,并且下面具有相同的底层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个变体。
假设您的sqldf
版本支持common table expressions(SQLite 3.8.3+),请考虑使用SUBSTR
和REPLACE
清除代码并将其加入聚合的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 |
使用最后在“注释”中可重复显示的输入执行左自连接。ltrim
删除A
的第一个实例的代码左侧的任何R
或DF
,然后substr
取下5个字符。将其与DF
的Code
的第二个实例匹配。如果可以在数字前面加上其他字母,则将它们包括在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)