Количество значений, разделенных запятой в символьной строке

У меня есть этот пример данных

d<-"30,3"
class(d)

У меня есть эти объекты символа в одном столбце в моем рабочем фрейме данных, и мне нужно определить, сколько у него чисел.

Я попытался использовать length(d), но он говорит 1

После поиска решения здесь я пробовал

eval(parse(text='d'))
as.numeric(d)
as.vector.character(d)

Но это все еще не работает.

Любой простой подход для решения этой проблемы?

Ответы

Ответ 1

Эти два подхода кажутся короткими, работают над векторами строк, не требуют затрат на явное построение разделительной строки и не используют никаких пакетов. Здесь d - вектор строк, таких как d <- c("1,2,3", "5,2"):

1) count.fields

count.fields(textConnection(d), sep = ",")

2) gregexpr

lengths(gregexpr(",", d)) + 1

Ответ 2

Вы можете использовать scan.

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

Или используя stri_split из stringi. Это должно принимать как классы character, так и factor без прямого преобразования символа с помощью as.character

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

Вы можете сделать count с помощью base R на

length(v1)
#[1] 2

или

nchar(gsub('[^,]', '', d))+1
#[1] 2

Визуализируйте regex

 [^,]

Regular expression visualization

Демоверсия Debuggex

Update

Если 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

Просто проверить

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

Ответ 3

Вот возможность

> as.numeric(unlist(strsplit("30,3", ",")))
# 30  3

Ответ 4

Вы также можете попробовать stringi пакет stri_count_* funcitons (должен быть очень эффектным)

library(stringi)
stri_count_regex(d, "\\d+")
## [1] 2
stri_count_fixed(d, ",") + 1
## [1] 2

stringr пакет имеет аналогичную функциональность

library(stringr)
str_count(d, "\\d+")
## [1] 2

Update:

Если вы хотите подмножить набор данных по векторам длины 2, можете попробовать

df[stri_count_regex(df$d, "\\d+") == 2,, drop = FALSE]
#      d
# 2 30,5

Или проще

subset(df, stri_count_regex(d, "\\d+") == 2)
#      d
# 2 30,5

Обновление # 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