data.frame(
authors = c(
"Drijgers RL, Verhey FR, Leentjens AF, Kahler S, Aalten P.",
"Drijgers RL, Verhey FR, Leentjens AF, Kahler S",
"Drijgers RL, Verhey FR, Leentjens AF",
"Drijgers RL, Verhey FR",
"Drijgers RL"
),
stringsAsFactors = FALSE
) -> sample_df
cbind.data.frame( # add the columns to the original data frame after the do.cal() completes
sample_df,
do.call( # turn the list created with lapply below into a data frame
rbind.data.frame,
lapply(
strsplit(sample_df$authors, ", "), # split at comma+space
function(x) {
data.frame( # pull first/last into a data frame
first = x[1],
last = if (length(x) < 2) NA_character_ else x[length(x)], # NA last if only one author
stringsAsFactors = FALSE
)
}
)
)
)
## authors first last
## 1 Drijgers RL, Verhey FR, Leentjens AF, Kahler S, Aalten P. Drijgers RL Aalten P.
## 2 Drijgers RL, Verhey FR, Leentjens AF, Kahler S Drijgers RL Kahler S
## 3 Drijgers RL, Verhey FR, Leentjens AF Drijgers RL Leentjens AF
## 4 Drijgers RL, Verhey FR Drijgers RL Verhey FR
## 5 Drijgers RL Drijgers RL <NA>
以上内容在性能方面糟糕。我制作了 stringi 匹配组提取版本,但 arg0naut 的 仍然 更快 并且 我还优化了 arg0naut 的一点,因为只需要在左侧进行空格剥离:
library(stringi)
data.frame(
authors = c(
"Drijgers RL, Verhey FR, Leentjens AF, Kahler S, Aalten P.",
"Drijgers RL, Verhey FR, Leentjens AF, Kahler S",
"Drijgers RL, Verhey FR, Leentjens AF",
"Drijgers RL, Verhey FR",
"Drijgers RL"
),
stringsAsFactors = FALSE
) -> sample_df
# make some copies since we're modifying in-place now
s1 <- s2 <- sample_df
microbenchmark::microbenchmark(
stri_regex = {
s1$first <- stri_match_first_regex(s1$authors, "^([^,]+)")[,2]
s1$last <- stri_trim_left(stri_match_last_regex(s1$authors, "([^,]+)$")[,2])
s1$last <- ifelse(s1$last == s1$first, NA_character_, s1$last)
},
extract_authors = {
s2[["first"]] <- ifelse(
grepl(",", s2[["authors"]]), gsub(",.*", "", s2[["authors"]]), s2[["authors"]]
)
s2[["last"]] <- ifelse(
grepl(",", s2[["authors"]]), trimws(gsub(".*,", "", s2[["authors"]]), "left"), NA_character_
)
}
)
结果:
## Unit: microseconds
## expr min lq mean median uq max neval
## stri_regex 236.948 265.8055 331.5695 291.6610 334.1685 1002.921 100
## extract_authors 127.584 150.8490 217.1192 162.4625 227.9995 1130.913 100
identical(s1, s2)
## [1] TRUE
s1
## authors first last
## 1 Drijgers RL, Verhey FR, Leentjens AF, Kahler S, Aalten P. Drijgers RL Aalten P.
## 2 Drijgers RL, Verhey FR, Leentjens AF, Kahler S Drijgers RL Kahler S
## 3 Drijgers RL, Verhey FR, Leentjens AF Drijgers RL Leentjens AF
## 4 Drijgers RL, Verhey FR Drijgers RL Verhey FR
## 5 Drijgers RL Drijgers RL <NA>