2014-04-27 95 views
7

我在我们称为v1的变量中有一个字符串。该字符串表示图片编号,并采用“图片27 + 28”的形式。我想提取第一个数字并将其存储在一个名为item的新变量中。R从字符串中提取第一个数字

,我已经尝试了一些代码:

item <- unique(na.omit(as.numeric(unlist(strsplit(unlist(v1),"[^0-9]+"))))) 

这工作得很好,直到我来到这去的列表:

[1,] "Pic 26 + 25" 
[2,] "Pic 27 + 28" 
[3,] "Pic 28 + 27" 
[4,] "Pic 29 + 30" 
[5,] "Pic 30 + 29" 
[6,] "Pic 31 + 32" 

在这一点上,我得到更多的数字比我想,因为它也抓住了其他唯一的数字(25)。

我已经尝试过用gsub做,但没有任何工作。帮助将不胜感激!

+0

将来我会有100+图片。例如,它会是“图片105 + 104”吗? –

回答

9

我假设你想提取每个字符串中的两个数字的第一个。

您可以使用stri_extract_first_regex函数从stringi包:

library(stringi) 
stri_extract_first_regex(c("Pic 26+25", "Pic 1,2,3", "no pics"), "[0-9]+") 
## [1] "26" "1" NA 
+0

这工作出色,谢谢! – kneijenhuijs

1

要跟进您的strsplit尝试:

# split the strings 
l <- strsplit(x = c("Pic 26 + 25", "Pic 27 + 28"), split = " ") 
l 
# [[1]] 
# [1] "Pic" "26" "+" "25" 
# 
# [[2]] 
# [1] "Pic" "27" "+" "28" 

# extract relevant part from each list element and convert to numeric 
as.numeric(lapply(l , `[`, 2)) 
# [1] 26 27 
3

在回应下面我们使用这个测试数据:

# test data 
v1 <- c("Pic 26 + 25", "Pic 27 + 28", "Pic 28 + 27", "Pic 29 + 30", 
"Pic 30 + 29", "Pic 31 + 32") 

1) gsubfn

library(gsubfn) 

strapply(v1, "(\\d+).*", as.numeric, simplify = c) 
## [1] 26 27 28 29 30 31 

2)子这不需要软件包,但确实涉及稍长的正则表达式:

as.numeric(sub("\\D*(\\d+).*", "\\1", v1)) 
## [1] 26 27 28 29 30 31 

3)函数read.table这涉及没有正则表达式或程序包:

read.table(text = v1, fill = TRUE)[[2]] 
## [1] 26 27 28 29 30 31 

在这个特定的例子中,可以省略,但如果v1的组件具有不同数量的字段,则可能需要它。

1

您可以使用filesstrings程序包中的first_number()函数很好地执行此操作,或者对于更常见的需求,可以使用nth_number()函数。通过install.packages("filesstrings")安装它。

library(filesstrings) 
#> Loading required package: stringr 
strings <- c("Pic 26 + 25", "Pic 27 + 28", "Pic 28 + 27", 
      "Pic 29 + 30", "Pic 30 + 29", "Pic 31 + 32") 
first_number(strings) 
#> [1] 26 27 28 29 30 31 
nth_number(strings, n = 1) 
#> [1] 26 27 28 29 30 31 
1

随着str_extractstringr

library(stringr) 

vec = c("Pic 26 + 25", "Pic 27 + 28", "Pic 28 + 27", 
     "Pic 29 + 30", "Pic 30 + 29", "Pic 31 + 32") 

str_extract(v1, "[0-9]+") 
# [1] "26" "27" "28" "29" "30" "31"