R 子集字符串和返回字符串

R 子集字符串和返回字符串,r,dplyr,data.table,R,Dplyr,Data.table,我想知道是否有一个干净的解决方案使用data.table来解决以下问题,可能使用其他软件包,比如stringr 假设我有下面的数据表 DT <- data.table(name = c("Carlos", "Henry", "John"), ID = c("US115115, CH123232, AB155, US4445", "CH112, BB53", "US57677777")) 我想做的是创建另一个列ID2,比如说,它接受列ID并只提取“美国标识”,然后创建一个新列,这

我想知道是否有一个干净的解决方案使用data.table来解决以下问题,可能使用其他软件包,比如stringr

假设我有下面的数据表

DT <- data.table(name = c("Carlos", "Henry", "John"), 
    ID = c("US115115, CH123232, AB155, US4445", "CH112, BB53", "US57677777"))
我想做的是创建另一个列ID2,比如说,它接受列ID并只提取“美国标识”,然后创建一个新列,这样最终的数据表应该如下所示:

     name                                ID              ID2
1: Carlos US115115, CH123232, AB155, US4445 US115115, US4445
2:  Henry                       CH112, BB53               NA
3:   John                        US57677777       US57677777                     
其中每个元素都是一个字符串。我已经能够编写一个版本,其中它接受第一个“美国身份”并丢弃其余的,但是我还没有找到一个处理多重性的解决方案

任何帮助都将不胜感激

一种可能的方法:

DT[, ID2 := sapply(strsplit(ID, ","), 
    function(s) paste(s[grepl("\\s*US", s)], collapse=","))]
输出:

     name                                ID              ID2
1: Carlos US115115, CH123232, AB155, US4445 US115115, US4445
2:  Henry                       CH112, BB53                 
3:   John                        US57677777       US57677777
一种可能的办法:

DT[, ID2 := sapply(strsplit(ID, ","), 
    function(s) paste(s[grepl("\\s*US", s)], collapse=","))]
输出:

     name                                ID              ID2
1: Carlos US115115, CH123232, AB155, US4445 US115115, US4445
2:  Henry                       CH112, BB53                 
3:   John                        US57677777       US57677777

以下是从@thelatemail和@chinsoon12得到的一些建议

DT$ID1 <- sapply(strsplit(DT$ID, ",\\s*"), function(x) 
                            toString(grep("^US", x, value = TRUE)))
DT
#     name                                ID              ID1
#1: Carlos US115115, CH123232, AB155, US4445 US115115, US4445
#2:  Henry                       CH112, BB53                 
#3:   John                        US57677777       US57677777

您可以将上述两个选项合并到
dplyr
链中,但是使用
dplyr
tidyr
的另一个选项将使用
单独的行
,这对于这个特定的问题来说可能是一种过度使用。我们可以从
stringr
中使用
stru子集
,它与
grep(“^US”,x,value=TRUE)
相同


以下是从@thelatemail和@chinsoon12得到的一些建议

DT$ID1 <- sapply(strsplit(DT$ID, ",\\s*"), function(x) 
                            toString(grep("^US", x, value = TRUE)))
DT
#     name                                ID              ID1
#1: Carlos US115115, CH123232, AB155, US4445 US115115, US4445
#2:  Henry                       CH112, BB53                 
#3:   John                        US57677777       US57677777

您可以将上述两个选项合并到
dplyr
链中,但是使用
dplyr
tidyr
的另一个选项将使用
单独的行
,这对于这个特定的问题来说可能是一种过度使用。我们可以从
stringr
中使用
stru子集
,它与
grep(“^US”,x,value=TRUE)
相同


我们可以使用
stru extract
提取以“我们”开头的单词

或使用
gsub

DT[, ID2 := gsub("(\\bUS\\S*)(*SKIP)(*F)|.", "", ID, perl = TRUE)]

或者使用
tidyverse

library(tidyverse)
DT %>%
    mutate(ID2 = str_extract_all(ID, "\\bUS\\S*") %>%
                   map(toString))

或者使用
gregexpr

DT$ID2 <- sapply(regmatches(DT$ID, gregexpr("\\bUS\\S*", DT$ID)), toString)

DT$ID2我们可以使用
stru extract
提取以“US”开头的单词

或使用
gsub

DT[, ID2 := gsub("(\\bUS\\S*)(*SKIP)(*F)|.", "", ID, perl = TRUE)]

或者使用
tidyverse

library(tidyverse)
DT %>%
    mutate(ID2 = str_extract_all(ID, "\\bUS\\S*") %>%
                   map(toString))

或者使用
gregexpr

DT$ID2 <- sapply(regmatches(DT$ID, gregexpr("\\bUS\\S*", DT$ID)), toString)

DT$ID2如果您将正则表达式更改为
,\\s*“
,您可以避免使用
trimws
,但这对我来说似乎很好。另外,我认为
sapply(strsplit(DT$ID,”),函数toString(grep(^US),trimws,value=TRUE))
会短一点吗?谢谢,@latemail。Ronaksah说:“我已经把你的意见纳入了解决方案,非常好。”。你也应该把它贴出来,我发现它很有用,因为我知道
toString
确实是
字符串,如果你把正则表达式改成
“,\\s*”
,你可以避免使用
trimws
,但这对我来说似乎很好。我还认为
很有用(strsplit(DT$ID,“,”),函数toString(grep(“^US”,trimws),value=TRUE)))
会短一点吗?谢谢,@latemail。Ronaksah说:“我已经把你的意见纳入了解决方案,非常好。”。您也应该发布它,我发现它很有用,因为我了解到
toString
确实
string