我有数据,其中一些项目是以“|”分隔的数字,如:
head(mintimes)
[1] "3121|3151" "1171" "1351|1381" "1050" "" "122"
head(minvalues)
[1] 14 10 11 31 Inf 22
我想要做的是提取所有时间并将它们与最小值匹配。最终得到类似的东西:
times values
3121 14
3151 14
1171 10
1351 11
1381 11
1050 31
122 22
我已尝试strsplit(mintimes, "|")
而我已尝试过str_extract(mintimes, "[0-9]+")
,但它们似乎无效。有什么想法吗?
答案 0 :(得分:6)
|
是正则表达式元字符。从字面上看,这些特殊字符需要使用[]
或\\
进行转义(或者您可以在某些函数中使用fixed = TRUE
)。因此,您对strsplit()
的致电应该是
strsplit(mintimes, "[|]")
或
strsplit(mintimes, "\\|")
或
strsplit(mintimes, "|", fixed = TRUE)
关于使用stringr
函数的其他尝试,str_extract_all()
似乎可以解决问题。
library(stringr)
str_extract_all(mintimes, "[0-9]+")
要获得所需的结果,
> mintimes <- c("3121|3151", "1171", "1351|1381", "1050", "", "122")
> minvalues <- c(14, 10, 11, 31, Inf, 22)
> s <- strsplit(mintimes, "[|]")
> data.frame(times = as.numeric(unlist(s)),
values = rep(minvalues, sapply(s, length)))
# times values
# 1 3121 14
# 2 3151 14
# 3 1171 10
# 4 1351 11
# 5 1381 11
# 6 1050 31
# 7 122 22
答案 1 :(得分:4)
默认情况下strsplit
使用正则表达式和&#34; |&#34;进行拆分是正则表达式语法中的特殊字符。你可以逃避它
strsplit(mintimes,"\\|")
或者只是将fixed = T设置为不使用正则表达式
strsplit(mintimes,"|", fixed=T)
答案 2 :(得分:3)
我编写了一个名为cSplit
的函数,它对这些类型的东西很有用。你可以从我的要点中得到它:https://gist.github.com/mrdwab/11380733
用法是:
cSplit(data.table(mintimes, minvalues), "mintimes", "|", "long")
# mintimes minvalues
# 1: 3121 14
# 2: 3151 14
# 3: 1171 10
# 4: 1351 11
# 5: 1381 11
# 6: 1050 31
# 7: 122 22
它还有一个广泛的&#34;设置,以防对您有用:
cSplit(data.table(mintimes, minvalues), "mintimes", "|", "wide")
# minvalues mintimes_1 mintimes_2
# 1: 14 3121 3151
# 2: 10 1171 NA
# 3: 11 1351 1381
# 4: 31 1050 NA
# 5: Inf NA NA
# 6: 22 122 NA
注意:输出为data.table
。
答案 3 :(得分:2)
正如其他人所提到的,你需要转义|
以将其字面包含在正则表达式中。与往常一样,我们可以通过多种方式为这只猫设置皮肤,这是使用stringr
进行此操作的唯一方法:
x <- c("3121|3151", "1171", "1351|1381", "1050", "", "122")
library(stringr)
unlist(str_extract_all(x, "\\d+"))
# [1] "3121" "3151" "1171" "1351" "1381" "1050" "122"
如果您在数字字符串中有任何小数点,这将无法按预期工作,因此以下(除了|
之外的任何内容)可能更安全:
unlist(str_extract_all(x, '[^|]+'))
# [1] "3121" "3151" "1171" "1351" "1381" "1050" "122"
无论哪种方式,您可能希望将结果包装在as.numeric
。
答案 4 :(得分:2)
这是使用stri_split_fixed
包中的stringi
的另一种解决方案。作为附加价值,我们还会使用mapply
和do.call
。
输入数据:
mintimes <- c("3121|3151", "1171", "1351|1381", "1050", "", "122")
minvalues <- c(14, 10, 11, 31, Inf, 22)
拆分mintimes
w.r.t. |
并转换为数字:
library("stringi")
mintimes <- lapply(stri_split_fixed(mintimes, "|"), as.numeric)
## [[1]]
## [1] 3121 3151
##
## [[2]]
## [1] 1171
##
## [[3]]
## [1] 1351 1381
##
## [[4]]
## [1] 1050
##
## [[5]]
## [1] NA
##
## [[6]]
## [1] 122
将每个minvalues
与相应的mintimes
tmp <- mapply(cbind, mintimes, minvalues)
## [[1]]
## [,1] [,2]
## [1,] 3121 14
## [2,] 3151 14
##
## [[2]]
## [,1] [,2]
## [1,] 1171 10
##
## [[3]]
## [,1] [,2]
## [1,] 1351 11
## [2,] 1381 11
##
## [[4]]
## [,1] [,2]
## [1,] 1050 31
##
## [[5]]
## [,1] [,2]
## [1,] NA Inf
##
## [[6]]
## [,1] [,2]
## [1,] 122 22
对所有6个矩阵进行行绑定&amp;删除NA
- 行:
res <- do.call(rbind, tmp)
res[!is.na(res[,1]),]
## [,1] [,2]
## [1,] 3121 14
## [2,] 3151 14
## [3,] 1171 10
## [4,] 1351 11
## [5,] 1381 11
## [6,] 1050 31
## [7,] 122 22
答案 5 :(得分:1)
要获得所需的输出,请尝试以下方法:
library(dplyr)
Split.Times <- function(x) {
mintimes <- as.numeric(unlist(strsplit(as.character(x$mintimes), "\\|")))
return(data.frame(mintimes = mintimes, minvalues = x$minvalues, stringsAsFactors=FALSE))
}
df <- data.frame(mintimes, minvalues, stringsAsFactors=FALSE)
df %>%
filter(mintimes != "") %>%
group_by(mintimes) %>%
do(Split.Times(.))
这会产生:
mintimes minvalues
1 1050 31
2 1171 10
3 122 22
4 1351 11
5 1381 11
6 3121 14
7 3151 14
(我从my answer here借来 - 这几乎是同一个问题/问题)
答案 6 :(得分:1)
这是一个qdap
包方法:
mintimes <- c("3121|3151", "1171", "1351|1381", "1050", "", "122")
minvalues <- c(14, 10, 11, 31, Inf, 22)
library(qdap)
list2df(setNames(strsplit(mintimes, "\\|"), minvalues), "times", "values")
## times values
## 1 3121 14
## 2 3151 14
## 3 1171 10
## 4 1351 11
## 5 1381 11
## 6 1050 31
## 7 122 22
答案 7 :(得分:0)
您可以使用[:punct:]
strsplit(mintimes, "[[:punct:]]")