我正在尝试按模型和引擎分隔我的列VEHICLE_TYPE
。代码可以是普通的 SQL 或 R 代码。
我的数据如下:
MODEL VEHICLE_TYPE
77 Bora Bora 1.6
79 Ducato Ducato 15 120 Multijet
80 Ducato Ducato 15 120 Multijet
87 Astra Astra 1.7 CDTI
88 406 406 2.0 HDi
89 406 406 2.0 HDi
90 Focus C-MAX Focus C-MAX 1.6 TDCi
91 Focus C-MAX Focus C-MAX 1.6 TDCi
92 Focus C-MAX Focus C-MAX 1.6 TDCi
93 Focus C-MAX Focus C-MAX 1.6 TDCi
94 Focus C-MAX Focus C-MAX 1.6 TDCi
97 S-Klasse S 320 CDI
98 S-Klasse S 320 CDI
99 S-Klasse S 320 CDI
我想收到这样的信息:
MODEL VEHICLE TYPE
Bora 1.6
Ducato 15 120 Multijet
... ...
Focus C-Max 1.6 TDCi
问题是,VEHICLE_TYPE可以有不同的长度和不同的空格数,我可以将它们分开。
我尝试使用 gsub 和正则表达式,但没有工作,但 strsplit 有效。远离我真正想要的东西,我已经没有想法,现在需要一些帮助。
> strsplit(as.character(test$VEHICLE_TYPE)," ")
[[1]]
[1] "Bora" "1.6"
[[2]]
[1] "Ducato" "15" "120" "Multijet"
[[3]]
[1] "Ducato" "15" "120" "Multijet"
[[4]]
[1] "Astra" "1.7" "CDTI"
[[5]]
[1] "406" "2.0" "HDi"
[[6]]
[1] "406" "2.0" "HDi"
[[7]]
[1] "Focus" "C-MAX" "1.6" "TDCi"
[[8]]
[1] "Focus" "C-MAX" "1.6" "TDCi"
[[9]]
[1] "Focus" "C-MAX" "1.6" "TDCi"
[[10]]
[1] "Focus" "C-MAX" "1.6" "TDCi"
[[11]]
[1] "Focus" "C-MAX" "1.6" "TDCi"
[[12]]
[1] "S" "320" "CDI"
答案 0 :(得分:1)
我猜测有人会用比这更简单的方式知道正则表达式的方法,但由于我是一个正则表达式,这是我的尝试。按空格拆分,然后折叠第一个“数字”值之后的所有内容。
library( magrittr )
df[['VEHICLE_TYPE']] %<>%
strsplit( " " ) %>%
sapply( function(x) paste(
x[ grep( "[[:digit:]]", x )[1] : length(x) ],
collapse = " " )
)
结果
> df
# # A tibble: 14 × 2
# MODEL VEHICLE_TYPE
# <chr> <chr>
# 1 Bora 1.6
# 2 Ducato 15 120 Multijet
# 3 Ducato 15 120 Multijet
# 4 Astra 1.7 CDTI
# 5 406 406 2.0 HDi
# 6 406 406 2.0 HDi
# 7 Focus C-MAX 1.6 TDCi
# 8 Focus C-MAX 1.6 TDCi
# 9 Focus C-MAX 1.6 TDCi
# 10 Focus C-MAX 1.6 TDCi
# 11 Focus C-MAX 1.6 TDCi
# 12 S-Klasse 320 CDI
# 13 S-Klasse 320 CDI
# 14 S-Klasse 320 CDI
或者,如果您希望按 last 数值进行拆分,而不是 first :
df[['VEHICLE_TYPE']] %<>%
strsplit( " " ) %>%
sapply( function(x) paste(
x[ tail( grep( "[[:digit:]]", x ), 1 ) : length(x) ],
collapse = " " )
)
> df
# # A tibble: 14 × 2
# MODEL VEHICLE_TYPE
# <chr> <chr>
# 1 Bora 1.6
# 2 Ducato 120 Multijet
# 3 Ducato 120 Multijet
# 4 Astra 1.7 CDTI
# 5 406 2.0 HDi
# 6 406 2.0 HDi
# 7 Focus C-MAX 1.6 TDCi
# 8 Focus C-MAX 1.6 TDCi
# 9 Focus C-MAX 1.6 TDCi
# 10 Focus C-MAX 1.6 TDCi
# 11 Focus C-MAX 1.6 TDCi
# 12 S-Klasse 320 CDI
# 13 S-Klasse 320 CDI
# 14 S-Klasse 320 CDI
编辑:如果你有一些没有任何数值的行,你可能需要一些额外的修补:
df[['VEHICLE_TYPE']] %<>%
strsplit( " " ) %>%
sapply( function(x) paste(
if( length( grep( "[[:digit:]]", x ) ) > 1L ) {
x[ tail( grep( "[[:digit:]]", x ), 1 ) : length(x) ]
} else { x },
collapse = " " )
)
答案 1 :(得分:0)
正则表达式的示例
with s(id,model,type) as (
select 77,'Bora','Bora 1.6' from dual union all
select 79,'Ducato','Ducato 15 120 Multijet' from dual union all
select 80 ,'Ducato','Ducato 15 120 Multijet' from dual union all
select 87 ,'Astra','Astra 1.7 CDTI' from dual union all
select 88 ,'406','406 2.0 HDi' from dual union all
select 89 ,'406','406 2.0 HDi' from dual union all
select 90 ,'Focus C-MAX','Focus C-MAX 1.6 TDCi' from dual union all
select 91 ,'Focus C-MAX','Focus C-MAX 1.6 TDCi' from dual union all
select 92 ,'Focus C-MAX','Focus C-MAX 1.6 TDCi' from dual union all
select 93 ,'Focus C-MAX','Focus C-MAX 1.6 TDCi' from dual union all
select 94 ,'Focus C-MAX','Focus C-MAX 1.6 TDCi' from dual union all
select 97 ,'S-Klasse','S 320 CDI' from dual union all
select 98 ,'S-Klasse','S 320 CDI' from dual union all
select 99 ,'S-Klasse','S 320 CDI' from dual
)
select regexp_substr(type,'\d+(\.\d+)?\s*\w*$') /*cut part with model*/
from s
答案 2 :(得分:0)
以下是使用 gsub
的替代解决方案df$VEHICLE_TYPE <- gsub(".+ ([0-9.]+(?: [^ ]+)?)$", "\\1", df$VEHICLE_TYPE)
> df
# MODEL VEHICLE_TYPE
# 1 Bora 1.6
# 2 Ducato 120 Multijet
# 3 Ducato 120 Multijet
# 4 Astra 1.7 CDTI
# 5 406 2.0 HDi
# 6 406 2.0 HDi
# 7 Focus C-MAX 1.6 TDCi
# 8 Focus C-MAX 1.6 TDCi
# 9 Focus C-MAX 1.6 TDCi
# 10 Focus C-MAX 1.6 TDCi
# 11 Focus C-MAX 1.6 TDCi
# 12 S-Klasse 320 CDI
# 13 S-Klasse 320 CDI
# 14 S-Klasse 320 CDI
我假设车辆类型总是在最后并且遵循这种模式:(1)数字字符组(0到9和点),例如1.6
或(2)组合数字字符和组合任何其他字符,以空格分隔(例如120 Multijet
,2.0 HDi
)
更新:处理308 1.6i Flex和Cherokee 2.8 CRD 4x4
df$VEHICLE_TYPE <- gsub(".+ ([0-9.]+[a-z]?(?: [^ ]+)?(?: [^ ]+)?)$", "\\1", df$VEHICLE_TYPE)
# OR, simply grep "number" and everything after
# df$VEHICLE_TYPE <- gsub(".+ ([0-9.]+[a-z]? .+)$", "\\1", df$VEHICLE_TYPE)
> df
# MODEL VEHICLE_TYPE
# 1 Bora 1.6
# 2 Ducato 120 Multijet
# 3 Ducato 120 Multijet
# 4 Astra 1.7 CDTI
# 5 406 2.0 HDi
# 6 406 2.0 HDi
# 7 Focus C-MAX 1.6 TDCi
# 8 Focus C-MAX 1.6 TDCi
# 9 Focus C-MAX 1.6 TDCi
# 10 Focus C-MAX 1.6 TDCi
# 11 Focus C-MAX 1.6 TDCi
# 12 S-Klasse 320 CDI
# 13 S-Klasse 320 CDI
# 14 S-Klasse 320 CDI
# 15 308 1.6i Flex
# 16 Cherokee 2.8 CRD 4x4
答案 3 :(得分:0)
在Oracle中,您可以使用正则表达式^(.*?)\s+(\d.*)$
中的第一个和第二个匹配组:
SELECT REGEXP_SUBSTR( vehicle_type, '^(.*?)\s+(\d.*)$', 1, 1, NULL, 1 )
AS model,
REGEXP_SUBSTR( vehicle_type, '^(.*?)\s+(\d.*)$', 1, 1, NULL, 2 )
AS vehicle_type
FROM your_table;