根据R中的字母拆分具有不同组合的字符串
Split Character Strings with different combinations based on letter in R
我有一个大型数据框,其字符列包含不同的字符串组合。
例如
**Column1**
1.0.01.01
1.02.04.03 | E1.3
G1.2 | 5.01.03.2
30.02.01.04.02
I.1
10.04.03 | H1.256
我唯一感兴趣的是那些以字母开头的值。我想要的输出应该是这样的:
**Column1**
NA
E1.3
G1.2
NA
I.1
H1.256
测试数据:
structure(list(Column1 = c("1.0.01.01", "1.02.04.03 | E1.3",
"G1.2 | 5.01.03.2", "30.02.01.04.02", "I.1", "10.04.03 | H1.256")),
class = "data.frame", row.names = c(NA, -6L))
我想使用 grepl 或类似命令解决方案可能非常简单,但目前我缺少正确的开始想法。
如果以字符开头,您可以使用^[[:alpha:]]
查找grep
。
unlist(lapply(strsplit(x$Column1, " \| "), function(x)
grep("^[[:alpha:]]", x, value = TRUE)[1]))
#[1] NA "E1.3" "G1.2" NA "I.1" "H1.256"
如果周围没有空格:
unlist(lapply(strsplit(x$Column1, "\|"), function(x)
grep("^[[:alpha:]]", trimws(x), value = TRUE)[1]))
如果每行有多个匹配项(使用 ""
而不是 NA
):
unlist(lapply(strsplit(x$Column1, " \| "), function(x)
paste(grep("^[[:alpha:]]", x, value = TRUE), collapse = " | ")))
或使用sub
:
sub("^.*\b([[:alpha:]][^ ]+).*$|.*", "\1", x$Column1)
或使用 regexec
和 regmatches
tt <- regmatches(x$Column1, regexec("\b[[:alpha:]][^ ]*", x$Column1))
tt[lengths(tt)==0] <- NA;
unlist(tt)
您可以尝试这种方法,假设 df 是您的数据框,Column1 是您的列名。
stringr::str_extract(df$Column1, '[a-zA-Z]+\d*\.\d+')
[a-zA-Z] 搜索一个或多个字母,后跟零个或多个匹配的数字,后跟点,再后跟数字
输出:
[1] NA "E1.3" "G1.2" NA "I.1" "H1.256"
这是我试过的。您的数据名为 mydf
.
library(tidyverse)
library(stringi)
mutate(mydf,
newcol = unlist(stri_extract_all_regex(str = Column1,
pattern = "(?<=\s|^)[A-Z].*?(?=\s|$)")))
Column1 newcol
1 1.0.01.01 <NA>
2 1.02.04.03 | E1.3 E1.3
3 G1.2 | 5.01.03.2 G1.2
4 30.02.01.04.02 <NA>
5 I.1 I.1
6 10.04.03 | H1.256 H1.256
我的另一种方法如下。
mutate(mydf, group = 1:n()) %>%
separate_rows(Column1, sep = "\s\|\s") %>%
filter(grepl(x = Column1, pattern = "^[A-Z]")) %>%
complete(group = 1:nrow(mydf))
group Column1
<int> <chr>
1 1 NA
2 2 E1.3
3 3 G1.2
4 4 NA
5 5 I.1
6 6 H1.256
这是另一个使用 regmatches
的基础 R 解决方案
df <- within(df,
Column2 <- unlist(replace(u<<-regmatches(Column1,
gregexpr("\b[[:alpha:]][\.\d]+\b",
Column1,perl = TRUE)),
!lengths(u),
NA)))
这样
> df
Column1 Column2
1 1.0.01.01 <NA>
2 1.02.04.03 | E1.3 E1.3
3 G1.2 | 5.01.03.2 G1.2
4 30.02.01.04.02 <NA>
5 I.1 I.1
6 10.04.03 | H1.256 H1.256
我有一个大型数据框,其字符列包含不同的字符串组合。
例如
**Column1**
1.0.01.01
1.02.04.03 | E1.3
G1.2 | 5.01.03.2
30.02.01.04.02
I.1
10.04.03 | H1.256
我唯一感兴趣的是那些以字母开头的值。我想要的输出应该是这样的:
**Column1**
NA
E1.3
G1.2
NA
I.1
H1.256
测试数据:
structure(list(Column1 = c("1.0.01.01", "1.02.04.03 | E1.3",
"G1.2 | 5.01.03.2", "30.02.01.04.02", "I.1", "10.04.03 | H1.256")),
class = "data.frame", row.names = c(NA, -6L))
我想使用 grepl 或类似命令解决方案可能非常简单,但目前我缺少正确的开始想法。
如果以字符开头,您可以使用^[[:alpha:]]
查找grep
。
unlist(lapply(strsplit(x$Column1, " \| "), function(x)
grep("^[[:alpha:]]", x, value = TRUE)[1]))
#[1] NA "E1.3" "G1.2" NA "I.1" "H1.256"
如果周围没有空格:
unlist(lapply(strsplit(x$Column1, "\|"), function(x)
grep("^[[:alpha:]]", trimws(x), value = TRUE)[1]))
如果每行有多个匹配项(使用 ""
而不是 NA
):
unlist(lapply(strsplit(x$Column1, " \| "), function(x)
paste(grep("^[[:alpha:]]", x, value = TRUE), collapse = " | ")))
或使用sub
:
sub("^.*\b([[:alpha:]][^ ]+).*$|.*", "\1", x$Column1)
或使用 regexec
和 regmatches
tt <- regmatches(x$Column1, regexec("\b[[:alpha:]][^ ]*", x$Column1))
tt[lengths(tt)==0] <- NA;
unlist(tt)
您可以尝试这种方法,假设 df 是您的数据框,Column1 是您的列名。
stringr::str_extract(df$Column1, '[a-zA-Z]+\d*\.\d+')
[a-zA-Z] 搜索一个或多个字母,后跟零个或多个匹配的数字,后跟点,再后跟数字
输出:
[1] NA "E1.3" "G1.2" NA "I.1" "H1.256"
这是我试过的。您的数据名为 mydf
.
library(tidyverse)
library(stringi)
mutate(mydf,
newcol = unlist(stri_extract_all_regex(str = Column1,
pattern = "(?<=\s|^)[A-Z].*?(?=\s|$)")))
Column1 newcol
1 1.0.01.01 <NA>
2 1.02.04.03 | E1.3 E1.3
3 G1.2 | 5.01.03.2 G1.2
4 30.02.01.04.02 <NA>
5 I.1 I.1
6 10.04.03 | H1.256 H1.256
我的另一种方法如下。
mutate(mydf, group = 1:n()) %>%
separate_rows(Column1, sep = "\s\|\s") %>%
filter(grepl(x = Column1, pattern = "^[A-Z]")) %>%
complete(group = 1:nrow(mydf))
group Column1
<int> <chr>
1 1 NA
2 2 E1.3
3 3 G1.2
4 4 NA
5 5 I.1
6 6 H1.256
这是另一个使用 regmatches
df <- within(df,
Column2 <- unlist(replace(u<<-regmatches(Column1,
gregexpr("\b[[:alpha:]][\.\d]+\b",
Column1,perl = TRUE)),
!lengths(u),
NA)))
这样
> df
Column1 Column2
1 1.0.01.01 <NA>
2 1.02.04.03 | E1.3 E1.3
3 G1.2 | 5.01.03.2 G1.2
4 30.02.01.04.02 <NA>
5 I.1 I.1
6 10.04.03 | H1.256 H1.256