我有这个示例数据
d<-"30,3"
class(d)
我在工作数据框的一列中有这个角色对象,我需要能够识别它有多少个数字。
我尝试使用length(d)
,但它说1
在寻找解决方案后,我尝试了
eval(parse(text='d'))
as.numeric(d)
as.vector.character(d)
但它仍然无效。
解决这个问题的任何直接方法都是什么?
答案 0 :(得分:20)
您可以使用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
[^,]
如果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)
答案 1 :(得分:17)
这两种方法都很简短,处理字符串向量,不涉及显式构造拆分字符串的费用,也不使用任何包。此处d
是字符串的向量,例如d <- c("1,2,3", "5,2")
:
1)count.fields
count.fields(textConnection(d), sep = ",")
2)gregexpr
lengths(gregexpr(",", d)) + 1
答案 2 :(得分:11)
这是一种可能性
> as.numeric(unlist(strsplit("30,3", ",")))
# 30 3
答案 3 :(得分:10)
您还可以尝试stringi
包stri_count_*
个功能(应该非常有效)
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
<强>更新强>
如果要按长度为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
答案 4 :(得分:0)
接受的答案略有变化,不需要包装。使用示例d <- c("1,2,3", "5,2")
lengths(strsplit(d, ","))
> [1] 3 2
或作为data.frame
df <- data.frame(d = d)
df$counts <- lengths(strsplit(df$d, ","))
df
#----
d counts
1,2,3 3
5,2 2