在R中将数字字符串转换为数字列表

3

如果这个问题太简单了,我很抱歉。我知道如何在Python中实现它,但现在我需要在R中实现。

作为SQL查询的一部分,我会得到一个包含一些数字的变量(长度可能会变化),以字符串的形式呈现:

x <- "{0.5,0.25,0.75,0.5}" 

我可以去掉括号和逗号,变成这样:
library(stringr)
library(dplyr)
y <- x %>%
  str_remove_all("[{]") %>%
  str_remove_all("[}]") %>%
  strsplit(",")

...但我收到的输出仍然是一个字符串列表:

> y
[[1]]
[1] "0.5"  "0.25" "0.75" "0.5"

我该如何确保y始终是一个数字列表?


1
str_extract_all 函数来自于 stringr 包,你需要将其包含进来。 - smci
抱歉,在我的实际代码中,我只加载了 tidyverse,它提供了 dplyr 和 stringr,但是在可重现的示例中,我忘记需要 stringr 了。 - mmyoung77
当然。最好在一个干净的R会话中重新测试您的最小可重现示例。 - smci
4个回答

8

你可以在基础 R 中这样做:

as.numeric(strsplit(substr(x, 2, nchar(x) - 1), ',')[[1]])

或者

as.numeric(strsplit(gsub('[{]|[}]', '', x), ',')[[1]])

5
我们可以提取第一个列表元素并转换为数值。
library(stringr)
as.numeric(str_extract_all(x, "[0-9.]+")[[1]])
#[1] 0.50 0.25 0.75 0.50

或者使用 base R 中的regmatches/regexpr函数。

as.numeric(regmatches(x, gregexpr("[0-9.]+", x))[[1]])
#[1] 0.50 0.25 0.75 0.50

在删除花括号后,您可以使用scan
scan(text= gsub("[{}]", "", x), what = numeric(), sep="," , quiet = TRUE)

str_extract_all 函数在 stringr 包中而不是 dplyr 中。(原帖作者可能只想使用基础 R 来解决问题) - smci
根据OP的帖子,有一个名为str_remove的函数在stringr中。 - akrun
1
啊,是的。奇怪他们似乎认为它来自于dplyr而不是stringr - smci
1
正如我上面所说,在我的现实生活示例中,我只加载了tidyverse,但是在可重复的示例中,我忘记了我需要stringr。抱歉。 - mmyoung77

4
你可以使用 scan
scan(text=substr(x,2,nchar(x)-1),sep=",")
[1] 0.50 0.25 0.75 0.50

我不确定性能是否是一个问题,但我很好奇所以这里有一个基准测试:

在较长的字符串上:

x <- paste0("{",paste(1:1e4,collapse=","),"}")

as.numeric(str_extract_all(x, "[0-9.]+")[[1]])
library(stringr)
microbenchmark::microbenchmark(
ak1 = as.numeric(str_extract_all(x, "[0-9.]+")[[1]]),
ak2 = as.numeric(regmatches(x, gregexpr("[0-9.]+", x))[[1]]),
ak3 = scan(text= gsub("[{}]", "", x), what = numeric(), sep="," , quiet = TRUE),
mkr = as.numeric(strsplit(gsub("[{}]","",x), split = ",")[[1]]),
sat = as.numeric(unlist( strsplit( gsub("[^0-9.,]", "", x), ",") ) ),
ry1 = as.numeric(strsplit(substr(x, 2, nchar(x) - 1), ',')[[1]]),
ry2 = as.numeric(strsplit(gsub('[{]|[}]', '', x), ',')[[1]]),
mm  = scan(text=substr(x,2,nchar(x)-1),sep=",", quiet = TRUE),
unit = "relative" 
)

# Unit: relative
# expr       min        lq      mean    median        uq       max neval
# ak1  1.083862  1.081196  1.024354  1.075517  1.056627 0.3696952   100
# ak2 20.581096 19.829962 18.775549 19.599953 19.307974 5.7053902   100
# ak3  1.309869  1.313783  1.258867  1.314094  1.322486 0.3918785   100
# mkr  2.817353  2.765637  2.682597  2.761487  2.719283 0.9331140   100
# sat  2.908291  2.871177  2.784193  2.871431  2.815423 1.4278423   100
# ry1  2.521181  2.463614  2.329599  2.456323  2.423078 0.6853562   100
# ry2  2.932874  2.859785  2.778728  2.865958  2.828777 0.8790090   100
#  mm  1.000000  1.000000  1.000000  1.000000  1.000000 1.0000000   100

在原始的短字符串中:

# Unit: relative
# expr      min    lq     mean   median    uq      max neval
#  ak1 2.183908 2.520 2.513167 2.445887 2.464 4.383178   100
#  ak2 3.574713 3.625 3.573718 3.432900 3.412 6.752336   100
#  ak3 5.114943 4.860 4.746448 4.532468 4.620 5.981308   100
#  mkr 1.425287 1.360 1.344941 1.285714 1.336 1.355140   100
#  sat 1.873563 1.810 1.783697 1.753247 1.736 2.121495   100
#  ry1 1.000000 1.000 1.000000 1.000000 1.000 1.000000   100
#  ry2 1.471264 1.415 1.359581 1.354978 1.336 1.074766   100
#  mm  4.390805 4.400 4.314622 4.134199 4.224 6.682243   100

3

你可以尝试使用gsub先替换{},然后使用strsplit将其拆分为向量。最后,将其转换为数字,例如:

x <- "{0.5,0.25,0.75,0.5}" 
as.numeric(strsplit(gsub("[{}]","",x), split = ",")[[1]])
#[1] 0.50 0.25 0.75 0.50

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接