Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R:提取长度可变的字符串部分_R_String_Performance_Apply_Strsplit - Fatal编程技术网

R:提取长度可变的字符串部分

R:提取长度可变的字符串部分,r,string,performance,apply,strsplit,R,String,Performance,Apply,Strsplit,我有一个字符串列表(非常大,数百万行),我想从中提取特定部分 我首先在分号处拆分字符串,然后提取到特定的部分。它变得有点复杂,因为一行中有时有3段,有时有4段。但我感兴趣的部分总是最后和倒数第二部分 示例代码: dataStr = c("secAlways; secExtr1; secExtr2", "secSometimes; secAlways; secExtr1; secExtr2", "secSometimes; secAlways

我有一个字符串列表(非常大,数百万行),我想从中提取特定部分

我首先在分号处拆分字符串,然后提取到特定的部分。它变得有点复杂,因为一行中有时有3段,有时有4段。但我感兴趣的部分总是最后和倒数第二部分

示例代码:

dataStr = c("secAlways;  secExtr1; secExtr2",
            "secSometimes;  secAlways;  secExtr1; secExtr2",
            "secSometimes;  secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2",
            "secSometimes;  secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2")

splStr <- strsplit(dataStr, ";")
extr1 <- list()
extr2 <- list()

for (i in 1:length(splStr)) {
  extr1[i] <- head( tail(splStr[[i]], n=2), n=1)
  extr2[i] <- tail(splStr[[i]], n = 1)
}
dataStr=c(“secAlways;secExtr1;secExtr2”,
“有时;有时;有时;有时;有时1;有时2”,
“有时;有时;有时;有时;有时1;有时2”,
“secAlways;secExtr1;secExtr2”,
“secAlways;secExtr1;secExtr2”,
“secAlways;secExtr1;secExtr2”,
“有时;有时;有时;有时;有时1;有时2”,
“secAlways;secExtr1;secExtr2”,
“secAlways;secExtr1;secExtr2”,
“secAlways;secExtr1;secExtr2”)

splStr我认为您最好在这里使用regexp:

sub(".+; (.+?); (.+?)$", "\\2", dataStr)
这将抓住最后一项

sub(".+; (.+?); (.+?)$", "\\1", dataStr)

这将在最后一项之前获取该项。

我认为您最好在此处使用regexp:

sub(".+; (.+?); (.+?)$", "\\2", dataStr)
sub(".+; (.+?); (.+?)$", "\\1", dataStr)
这将抓住最后一项

sub(".+; (.+?); (.+?)$", "\\1", dataStr)

这将在最后一项之前抓取该项。

这样做可能会更快:

sub(".+; (.+?); (.+?)$", "\\1", dataStr)
str_list <- lapply(splStr, tail, 2)
do.call(rbind, str_list)

      [,1]         [,2]       
 [1,] "  secExtr1" " secExtr2"
 [2,] "  secExtr1" " secExtr2"
 [3,] "  secExtr1" " secExtr2"
 [4,] "  secExtr1" " secExtr2"
 [5,] "  secExtr1" " secExtr2"
 [6,] "  secExtr1" " secExtr2"
 [7,] "  secExtr1" " secExtr2"
 [8,] "  secExtr1" " secExtr2"
 [9,] "  secExtr1" " secExtr2"
[10,] "  secExtr1" " secExtr2"

stru list这样做可能更快:

str_list <- lapply(splStr, tail, 2)
do.call(rbind, str_list)

      [,1]         [,2]       
 [1,] "  secExtr1" " secExtr2"
 [2,] "  secExtr1" " secExtr2"
 [3,] "  secExtr1" " secExtr2"
 [4,] "  secExtr1" " secExtr2"
 [5,] "  secExtr1" " secExtr2"
 [6,] "  secExtr1" " secExtr2"
 [7,] "  secExtr1" " secExtr2"
 [8,] "  secExtr1" " secExtr2"
 [9,] "  secExtr1" " secExtr2"
[10,] "  secExtr1" " secExtr2"

stru list我们可以使用
stringi
vapply

library(stringi)
vapply(stri_split(dataStr, regex=';\\s*'), function(x) tail(x, 2), character(2))

我们可以使用
stringi
vapply

library(stringi)
vapply(stri_split(dataStr, regex=';\\s*'), function(x) tail(x, 2), character(2))

来自
stringr
解决方案的
word

stringr::word(dataStr, -2, -1,  sep = ';')
然后,您可以
strsplit
将它们作为两个不同的单词,即

do.call(rbind, strsplit(trimws(word(dataStr, -2, -1,  sep = ';')), '; '))
#      [,1]       [,2]      
# [1,] "secExtr1" "secExtr2"
# [2,] "secExtr1" "secExtr2"
# [3,] "secExtr1" "secExtr2"
# [4,] "secExtr1" "secExtr2"
# [5,] "secExtr1" "secExtr2"
# [6,] "secExtr1" "secExtr2"
# [7,] "secExtr1" "secExtr2"
# [8,] "secExtr1" "secExtr2"
# [9,] "secExtr1" "secExtr2"
#[10,] "secExtr1" "secExtr2"

来自
stringr
解决方案的
word

stringr::word(dataStr, -2, -1,  sep = ';')
然后,您可以
strsplit
将它们作为两个不同的单词,即

do.call(rbind, strsplit(trimws(word(dataStr, -2, -1,  sep = ';')), '; '))
#      [,1]       [,2]      
# [1,] "secExtr1" "secExtr2"
# [2,] "secExtr1" "secExtr2"
# [3,] "secExtr1" "secExtr2"
# [4,] "secExtr1" "secExtr2"
# [5,] "secExtr1" "secExtr2"
# [6,] "secExtr1" "secExtr2"
# [7,] "secExtr1" "secExtr2"
# [8,] "secExtr1" "secExtr2"
# [9,] "secExtr1" "secExtr2"
#[10,] "secExtr1" "secExtr2"
>str\u list do.call(rbind,str\u list)
[,1]                                           
[1,]“secAlways;secExtr1;secExtr2”
[2,]“有时秒;始终秒;第1秒;第2秒”
[3,]“有时秒;总是秒;第1秒;第2秒”
[4,]“secAlways;secExtr1;secExtr2”
[5,]“secAlways;secExtr1;secExtr2”
[6,]“secAlways;secExtr1;secExtr2”
[7,]“有时秒;始终秒;第1秒;第2秒”
[8,]“secAlways;secExtr1;secExtr2”
[9,]“secAlways;secExtr1;secExtr2”
[10,]“secAlways;secExtr1;secExtr2”
我不确定这是否有效?
>str\u list do.call(rbind,str\u list)
[,1]                                           
[1,]“secAlways;secExtr1;secExtr2”
[2,]“有时秒;始终秒;第1秒;第2秒”
[3,]“有时秒;总是秒;第1秒;第2秒”
[4,]“secAlways;secExtr1;secExtr2”
[5,]“secAlways;secExtr1;secExtr2”
[6,]“secAlways;secExtr1;secExtr2”
[7,]“有时秒;始终秒;第1秒;第2秒”
[8,]“secAlways;secExtr1;secExtr2”
[9,]“secAlways;secExtr1;secExtr2”
[10,]“secAlways;secExtr1;secExtr2”

我不确定这是否有效?

假设最后一段和最后第二段的字符数始终相同,可以通过以下方式使用
stringi
库实现这一点

我还假设您想要两个列表作为输出

library(stringi)

dataStr = c("secAlways;  secExtr1; secExtr2",
            "secSometimes;  secAlways;  secExtr1; secExtr2",
            "secSometimes;  secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2",
            "secSometimes;  secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2")

extr1 <- as.list(stringi::stri_sub(dataStr, from=-18, to=-11))
extr2 <- as.list(stringi::stri_sub(dataStr, from= -8))
库(stringi)
dataStr=c(“secAlways;secExtr1;secExtr2”,
“有时;有时;有时;有时;有时1;有时2”,
“有时;有时;有时;有时;有时1;有时2”,
“secAlways;secExtr1;secExtr2”,
“secAlways;secExtr1;secExtr2”,
“secAlways;secExtr1;secExtr2”,
“有时;有时;有时;有时;有时1;有时2”,
“secAlways;secExtr1;secExtr2”,
“secAlways;secExtr1;secExtr2”,
“secAlways;secExtr1;secExtr2”)

extr1假设最后一段和最后第二段的字符数始终相同,这可以通过使用
stringi
库通过以下方式实现

我还假设您想要两个列表作为输出

library(stringi)

dataStr = c("secAlways;  secExtr1; secExtr2",
            "secSometimes;  secAlways;  secExtr1; secExtr2",
            "secSometimes;  secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2",
            "secSometimes;  secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2",
            "secAlways;  secExtr1; secExtr2")

extr1 <- as.list(stringi::stri_sub(dataStr, from=-18, to=-11))
extr2 <- as.list(stringi::stri_sub(dataStr, from= -8))
库(stringi)
dataStr=c(“secAlways;secExtr1;secExtr2”,
“有时;有时;有时;有时;有时1;有时2”,
“有时;有时;有时;有时;有时1;有时2”,
“secAlways;secExtr1;secExtr2”,
“secAlways;secExtr1;secExtr2”,
“secAlways;secExtr1;secExtr2”,
“有时;有时;有时;有时;有时1;有时2”,
“secAlways;secExtr1;secExtr2”,
“secAlways;secExtr1;secExtr2”,
“secAlways;secExtr1;secExtr2”)


嗯,都一样。splStr是splitdatastr。regex方法实际上更快(至少在这个示例集上是如此)。它是一样的。splStr是拆分的dataStr。正则表达式方法实际上更快(至少在这个示例集上是这样)。在我的真实世界示例中,速度提高了27倍。在我的真实世界示例中,速度提高了27倍。这在这里的示例中有效,但在我的真实世界示例中失败:
Error in vapply(splStr,函数(x)tail(x,2),字符(2)):值必须是长度2,但有趣的是(x[[5487]])结果是长度1
@ulima2_u不清楚当少于2个案例时,该怎么办这在这里的示例中有效,但在我的真实示例中失败:
vapply中的错误(splStr,函数(x)tail(x,2),字符(2)):值的长度必须为2,但有趣(X[[5487]])结果是长度1
@ulima2\u不清楚当你少于2个案例时,该做什么我认为这不管用:两个部分仍然集中在同一个单元格中。编辑。我还使用了
trimws
删除前导/尾随空格great,现在可以工作了-谢谢!不过正则表达式的解决方案要快得多。是的,我希望如此艾德:可能吧,但我对正则表达式有点盲目,所以我尽量避免使用它们