从data.frame列中提取单词

时间:2015-11-25 14:06:31

标签: r dataframe extract

在我的数据中,有一个列如下:

df <- data.frame(status = c("GET/sfuksd1567","GET/sjsh787","POST/hsfhuks","GET/sfukfiezd17","POST/fshks"), stringsAsFactors = FALSE)

我想自动创建另一个列,它是变量状态的指示符,它只提取“GET”或“POST”,如df$ind=c("GET","GET","POST","GET","POST")

我尝试了substr功能,但我没有成功。

原始数据:

> df
           status
1  GET/sfuksd1567
2     GET/sjsh787
3    POST/hsfhuks
4 GET/sfukfiezd17
5      POST/fshks

预期结果:

> df
           status  ind
1  GET/sfuksd1567  GET
2     GET/sjsh787  GET
3    POST/hsfhuks POST
4 GET/sfukfiezd17  GET
5      POST/fshks POST

3 个答案:

答案 0 :(得分:10)

您可以使用正则表达式删除反斜杠后的所有内容

df$ind <- sub("/.*", "", df$status)
df
#            status  ind
# 1  GET/sfuksd1567  GET
# 2     GET/sjsh787  GET
# 3    POST/hsfhuks POST
# 4 GET/sfukfiezd17  GET
# 5      POST/fshks POST

或者如果你不喜欢正则表达式,你可以试试

library(tidyr)
separate(df, "status", c("ind", "status"))

或者

library(data.table) ## V1.9.6+
setDT(df)[, tstrsplit(status, "/")]

或者

read.table(text = df$status, sep = "/")

最后三个选项只会将status列拆分为两个独立的列。

答案 1 :(得分:3)

我们有:

df<-data.frame(status=c("GET/sfuksd1567","GET/sjsh787","POST/hsfhuks","GET/sfukfiezd17","POST/fshks"),stringsAsFactors=F)

你可以这样做:

df$ind<-sapply(1:nrow(df),function(x){strsplit(df$status,'/')[[x]][1]})

df$ind<-sapply(strsplit(df$status,'/'),`[[`,1)

两者都返回

df
           status  ind
1  GET/sfuksd1567  GET
2     GET/sjsh787  GET
3    POST/hsfhuks POST
4 GET/sfukfiezd17  GET
5      POST/fshks POST

基准:

microbenchmark(david=sub("/.*", "", df$status),etienne=sapply(strsplit(df$status,'/'),`[[`,1))

Unit: microseconds
    expr    min      lq     mean  median     uq     max neval cld
   david 25.198 25.8985 27.64456 26.5980 27.298 116.189   100  a 
 etienne 62.294 63.3440 65.13979 63.8695 65.094 128.088   100   b

答案 2 :(得分:2)

我们可以使用stri_extract_first_words

中的library(stringi)
library(stringi)
stri_extract_first_words(df$status)
#[1] "GET"  "GET"  "POST" "GET"  "POST"

tidyr的另一个选项是extract

extract(df, status, into='ind', '([^/]+)/.*', remove=FALSE)

基准

使用stri_extract_first_words,基准是:

david <- function() sub('/.*', '', df$status)
etienne <- function() sapply(strsplit(df$status,'/'),`[[`,1)
akrun <- function()stri_extract_first_words(df$status)
df <-  df[sample(1:nrow(df), 1e6, replace=TRUE),, drop=FALSE]
library(microbenchmark)
microbenchmark(david(), etienne(), akrun(), unit='relative', times=20L)
#Unit: relative
#      expr      min       lq     mean   median       uq      max neval
#   david() 1.826192 1.824263 1.781562 1.814156 1.788085 1.699008    20
# etienne() 4.935629 5.159218 5.136180 5.198875 5.137107 5.930806    20
#   akrun() 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000    20

注意:@David Arenburg的帖子中还有其他选项。我猜测sub版本更快。我错了。