我有一个字符串列表,其中不同的子字符串除以'_'字符,我想从此列表中获取特定的子字符串以形成新列表:
此字符串列表如下:
lista <- c('ORD_EVI_19870401_MAXI_002','CAB_EVI_19850301_MAXI_003','CAB_EVI_19850401_MAXI_001','PIC_EVI_19920301_MAXI_001','PIC_EVI_19920401_MAXI_003')
我知道这可行:
lista <- substr(lista, 9,12)
我正在寻找输出:
[1] "1987" "1985" "1985" "1992" "1992"
但是有时每个字符串的长度都不同,所以不起作用。
如何组合strsplit
和substr
函数以获取列表中每个元素中第三个子字符串的前四个字符?
答案 0 :(得分:2)
一种方法可能是:
substr(sapply(strsplit(list, "_", fixed = TRUE), "[", 3), 1, 4)
[1] "1987" "1985" "1985" "1992" "1992"
或者使用tstrsplit()
中的data.table
:
sapply(tstrsplit(list, "_", fixed = TRUE, keep = 3), substr, 1, 4)
只是方法的一小部分比较:
library(microbenchmark)
lst <- rep(list, 100000)
microbenchmark(
tmfmnk_strsplit = substr(sapply(strsplit(lst, "_", fixed = TRUE), "[", 3), 1, 4),
tmfmnk_tstrsplit = sapply(tstrsplit(lst, "_", fixed = TRUE, keep = 3), substr, 1, 4),
Ronak_Shah_strsplit = sapply(strsplit(lst, "_"), function(x) substr(x[3], 1, 4)),
Ronak_Shah_sub = sub("^(?:[^_]+_){2}(.{4}).*", "\\1", lst),
Sotos_stringr_word = substr(stringr::word(lst, 3, 3, sep = '_'), 1, 4),
Sotos_gsub = substr(gsub("\\D+", "", lst), 1, 4),
patL_1 = str_sub(str_split(lst, pattern = "_", simplify = TRUE)[,3], start = 1, end = 4),
patL_2 = str_split(lst, pattern = "_", simplify = TRUE)[,3] %>% str_sub(start = 1, end = 4),
times = 5
)
Unit: milliseconds
expr min lq mean median uq max neval
tmfmnk_strsplit 600.8501 615.2786 688.7693 618.1062 631.8959 977.7155 5
tmfmnk_tstrsplit 383.7881 392.2930 596.2255 428.4289 445.8589 1330.7584 5
Ronak_Shah_strsplit 4372.1978 4436.3701 4650.4455 4551.9226 4652.0911 5239.6461 5
Ronak_Shah_sub 737.3849 756.7462 773.2315 759.4766 777.2293 835.3204 5
Sotos_stringr_word 8298.2679 8459.3475 9452.5748 9954.5619 10255.8447 10294.8522 5
Sotos_gsub 1299.2949 1323.2183 1479.6777 1386.1354 1446.8309 1942.9089 5
patL_1 730.1206 731.3955 842.6071 813.4897 841.1782 1096.8517 5
patL_2 635.8529 656.1035 818.8592 669.6658 713.0357 1419.6380 5
答案 1 :(得分:2)
另一个想法是使用gsub
,即
substr(gsub('\\D+', '', list), 1, 4)
#[1] "1987" "1985" "1985" "1992" "1992"
还有stringr
程序包和(总是很有趣的)函数word
,即
substr(stringr::word(list, 3, 3, sep = '_'), 1, 4)
#[1] "1987" "1985" "1985" "1992" "1992"
答案 2 :(得分:2)
使用scanf
的另一种方法:
stringr
或相同,但传递代码:
library(stringr)
str_sub(str_split(list, pattern = "_", simplify = TRUE)[,3],
start = 1,
end = 4)
#[1] "1987" "1985" "1985" "1992" "1992"
答案 3 :(得分:1)
我们可以在"_"
上分割字符串,并提取第三部分的前4个字符。
sapply(strsplit(lista, "_"), function(x) substr(x[3], 1, 4))
#[1] "1987" "1985" "1985" "1992" "1992"
或者从here那里获得帮助的完整正则表达式解决方案
sub("^(?:[^_]+_){2}(.{4}).*", "\\1", lista)
#[1] "1987" "1985" "1985" "1992" "1992"
这将提取第二个下划线后的前4个字符。