计算由字符串中的逗号分隔的值

Bur*_*ury 17 r vector character

我有这个示例数据

d<-"30,3"
class(d)
Run Code Online (Sandbox Code Playgroud)

我在工作数据框的一列中有这个角色对象,我需要能够识别它有多少个数字.

我试过用length(d),但它说1

在寻找解决方案后,我试过了

eval(parse(text='d'))
as.numeric(d)
as.vector.character(d)
Run Code Online (Sandbox Code Playgroud)

但它仍然无效.

有什么简单的方法可以解决这个问题吗?

akr*_*run 20

你可以用scan.

 v1 <- scan(text=d, sep=',', what=numeric(), quiet=TRUE)
 v1
 #[1] 30  3
Run Code Online (Sandbox Code Playgroud)

或者使用stri_split来自stringi.这应该采用both characterfactorclass,而不使用明确转换为字符as.character

library(stringi)
v2 <- as.numeric(unlist(stri_split(d,fixed=',')))
v2
#[1] 30  3
Run Code Online (Sandbox Code Playgroud)

你可以做count使用base R

length(v1)
#[1] 2
Run Code Online (Sandbox Code Playgroud)

要么

nchar(gsub('[^,]', '', d))+1
#[1] 2
Run Code Online (Sandbox Code Playgroud)

可视化 regex

 [^,]
Run Code Online (Sandbox Code Playgroud)

正则表达式可视化

Debuggex演示

更新

If d是数据集中的列,df并且希望对具有等于位数的行进行子集化2

  d<-c("30,3,5","30,5") 
  df <- data.frame(d,stringsAsFactors=FALSE)
  df[nchar(gsub('[^,]', '',df$d))+1==2,,drop=FALSE]
  #    d
  #2 30,5
Run Code Online (Sandbox Code Playgroud)

只是为了测试

  df[nchar(gsub('[^,]', '',df$d))+1==10,,drop=FALSE]
  #[1] d
  #<0 rows> (or 0-length row.names)
Run Code Online (Sandbox Code Playgroud)


G. *_*eck 18

这两种方法都很简短,处理字符串向量,不涉及显式构造拆分字符串的费用,也不使用任何包.这d是一个字符串向量,例如d <- c("1,2,3", "5,2"):

1)count.fields

count.fields(textConnection(d), sep = ",")
Run Code Online (Sandbox Code Playgroud)

2)gregexpr

lengths(gregexpr(",", d)) + 1
Run Code Online (Sandbox Code Playgroud)


joh*_*nes 11

这是一种可能性

> as.numeric(unlist(strsplit("30,3", ",")))
# 30  3
Run Code Online (Sandbox Code Playgroud)


Dav*_*urg 10

你也可以试试stringi包功能stri_count_*(应该非常有效)

library(stringi)
stri_count_regex(d, "\\d+")
## [1] 2
stri_count_fixed(d, ",") + 1
## [1] 2
Run Code Online (Sandbox Code Playgroud)

stringr 包具有类似的功能

library(stringr)
str_count(d, "\\d+")
## [1] 2
Run Code Online (Sandbox Code Playgroud)

更新:

如果您想通过长度为2的向量对数据集进行子集,可以尝试

df[stri_count_regex(df$d, "\\d+") == 2,, drop = FALSE]
#      d
# 2 30,5
Run Code Online (Sandbox Code Playgroud)

或者更简单

subset(df, stri_count_regex(d, "\\d+") == 2)
#      d
# 2 30,5
Run Code Online (Sandbox Code Playgroud)

更新#2

这是一个基准,说明为什么人们应该考虑使用外部包(@rengis答案不包括在内,因为它没有回答问题)

library(microbenchmark)
library(stringi)
d <- rep("30,3", 1e4)

microbenchmark( akrun = nchar(gsub('[^,]', '', d))+1,
                GG1 = count.fields(textConnection(d), sep = ","),
                GG2 = sapply(gregexpr(",", d), length) + 1,
                DA1 = stri_count_regex(d, "\\d+"),
                DA2 = stri_count_fixed(d, ",") + 1)

# Unit: microseconds
#  expr       min         lq       mean     median        uq       max neval
# akrun  8817.950  9479.9485 11489.7282 10642.4895 12480.845  46538.39   100
#   GG1 55451.474 61906.2460 72324.0820 68783.9935 78980.216 150673.72   100
#   GG2 33026.455 43349.5900 60960.8762 51825.6845 72293.923 203126.27   100
#   DA1  4730.302  5120.5145  6206.8297  5550.7930  7179.536  10507.09   100
#   DA2   380.147   418.2395   534.6911   448.2405   597.259   2278.11   100
Run Code Online (Sandbox Code Playgroud)