分隔两个不同的分隔符并截断

问题描述 投票:0回答:3

我有一个小故事,例如

a <- as_tibble(c("201.1, 202 (abc) 203, 204", "301 / 302.22 def, 303"))

  value                  
  <chr>                  
1 201.1, 202 (abc) 203, 204
2 301 / 302.22 def, 303    

现在我想得到一个有两列的data.frame

[1,] 201.1  202
[2,] 301    302.22

通过剪切第二个数字之后的所有内容(第一行中的 202,第二行中的 302.22)并且用分隔符“,”或“/”分隔表达式的剩余部分以获得两列。

r delimiter strsplit
3个回答
5
投票

这里有几种方法。

1)单独 使用 tidyr 中的

separate
,如下所示,给出显示的 tibble/data.frame 。它自动确定列是数字。

library(tidyr)

a %>%
  separate("value", c("value1", "value2"),  sep = "[,/ ]+", extra = "drop")

## # A tibble: 2 × 2
##   value1 value2
##   <chr>  <chr> 
##  1 201.1  202   
##  2 301    302.22

2) 基础 R 使用基础 R 中的

strcapture
,如下所示。不需要任何包裹。

strcapture("([0-9.]+)[^0-9.]+([0-9.]+).*", a$value, 
  data.frame(value1 = numeric(0), value2 = numeric(0)))

##   value1 value2
## 1  201.1 202.00
## 2  301.0 302.22

3) read.pattern 使用 gsubfn 中的

read.pattern
。这使用与 (2) 中相同的正则表达式。它会自动确定列是数字,并使用与
text=
相同的
col.names=
read.table
参数,如果您熟悉的话,它们很容易记住。

library(gsubfn)

read.pattern(text = a$value, pattern = "([0-9.]+)[^0-9.]+([0-9.]+).*", 
  col.names = c("value1", "value2"))

##   value1 value2
## 1  201.1 202.00
## 2  301.0 302.22

注意

问题的输入

library(tibble)
a <- as_tibble(c("201.1, 202 (abc) 203, 204", "301 / 302.22 def, 303"))

2
投票

你可以尝试一下,

do.call(rbind, lapply(a$value, \(i) { 
            i1 <- regmatches(i, gregexpr("\\d+\\.?\\d*", i))[[1]]; return(i1[c(1, 2)])}))

     [,1]    [,2]    
[1,] "201.1" "202"   
[2,] "301"   "302.22"

2
投票

我的尝试:

b <- stringr::str_extract(a$value, "([\\.\\d]+)\\D+([\\.\\d]+)\\D+.*", group = c(1, 2))

正则表达式的目的是:

捕获组 1 = 一个或多个 [数字或 .s]
然后是一个或多个非数字
然后捕获组 2 = 一个或多个 [数字或 .s]
然后是一个或多个非数字
然后是任意数量的其他字符

仅返回捕获组 1 和 2。

编辑: 根据其他答案,我不必要地转义了

.
内的
[]
,因此可以通过将每个
[\\.\\d]+
替换为
[0-9.]+
来简化,这至少对我来说更易于阅读。

© www.soinside.com 2019 - 2024. All rights reserved.