R 基于第二个空格的条件数据帧字符串拆分
我有一个数据框,我想将第一列的文本字符串拆分为两列,但只在序列中的第二个空格之后。以下是一个示例:R 基于第二个空格的条件数据帧字符串拆分,r,string,tidyr,data-cleaning,R,String,Tidyr,Data Cleaning,我有一个数据框,我想将第一列的文本字符串拆分为两列,但只在序列中的第二个空格之后。以下是一个示例: test22 Ticker 1 Current SharePrice $6.57 MFM 2 Current NAV $7.11 MFM 3 Current Premium/Discount -7.59% MFM 4 52WkAvg SharePrice $6.55
test22 Ticker
1 Current SharePrice $6.57 MFM
2 Current NAV $7.11 MFM
3 Current Premium/Discount -7.59% MFM
4 52WkAvg SharePrice $6.55 MFM
5 52WkAvg NAV $7.21 MFM
6 52WkAvg Premium/Discount -9.19% MFM
从本质上讲,如果最终结果是一个数据帧,它有三列合计,并且price/%字段是它自己的单独列。谢谢 base中的一个选项是创建一个分隔符,
和子项
,然后使用read.csv
:
out <- cbind(read.csv(text = sub(" (\\S+)$", ",\\1", df1$test22),
header = FALSE, stringsAsFactors = FALSE), df1[2])
out
#. V1 V2 Ticker
#1 Current SharePrice $6.57 MFM
#2 Current NAV $7.11 MFM
#3 Current Premium/Discount -7.59% MFM
#4 52WkAvg SharePrice $6.55 MFM
#5 52WkAvg NAV $7.21 MFM
#6 52WkAvg Premium/Discount -9.19% MFM
数据
df1base中的一个选项是使用sub
创建一个分隔符,
,然后使用read.csv
:
out <- cbind(read.csv(text = sub(" (\\S+)$", ",\\1", df1$test22),
header = FALSE, stringsAsFactors = FALSE), df1[2])
out
#. V1 V2 Ticker
#1 Current SharePrice $6.57 MFM
#2 Current NAV $7.11 MFM
#3 Current Premium/Discount -7.59% MFM
#4 52WkAvg SharePrice $6.55 MFM
#5 52WkAvg NAV $7.21 MFM
#6 52WkAvg Premium/Discount -9.19% MFM
数据
df1这里有一个使用strsplit的选项
data.frame(do.call(rbind, strsplit(df$test22, '\\s(?!.*\\s)', perl = TRUE)),
Ticker=df$Ticker)
# X1 X2 Ticker
# 1 Current SharePrice $6.57 MFM
# 2 Current NAV $7.11 MFM
# 3 Current Premium/Discount -7.59% MFM
# 4 52WkAvg SharePrice $6.55 MFM
# 5 52WkAvg NAV $7.21 MFM
# 6 52WkAvg Premium/Discount -9.19% MFM
或使用gsub
gsub('.*\\s.*?\\s(.*)','\\1', df$test22, perl = TRUE)
# [1] "$6.57" "$7.11" "-7.59%" "$6.55" "$7.21" "-9.19%"
# or if factors
# gsub('.*\\s.*?\\s(.*)','\\1', as.character(df$test22), perl = TRUE)
第二个字符的优点是它真正考虑了第二个空格字符(与最后一个空格相对)。这里有一个使用strsplit的选项
data.frame(do.call(rbind, strsplit(df$test22, '\\s(?!.*\\s)', perl = TRUE)),
Ticker=df$Ticker)
# X1 X2 Ticker
# 1 Current SharePrice $6.57 MFM
# 2 Current NAV $7.11 MFM
# 3 Current Premium/Discount -7.59% MFM
# 4 52WkAvg SharePrice $6.55 MFM
# 5 52WkAvg NAV $7.21 MFM
# 6 52WkAvg Premium/Discount -9.19% MFM
或使用gsub
gsub('.*\\s.*?\\s(.*)','\\1', df$test22, perl = TRUE)
# [1] "$6.57" "$7.11" "-7.59%" "$6.55" "$7.21" "-9.19%"
# or if factors
# gsub('.*\\s.*?\\s(.*)','\\1', as.character(df$test22), perl = TRUE)
第二个字符的优点是它真正考虑了第二个空格字符(与最后一个空格相对)。这里有一个使用dplyr
和stringr
的选项:
library(dplyr)
library(stringr)
data <-
tibble(test22 = c("Current SharePrice $6.57",
"Current NAV $7.11",
"Current Premium/Discount -7.59%",
"52WkAvg SharePrice $6.55",
"52WkAvg NAV $7.21",
"52WkAvg Premium/Discount -9.19%"),
Ticker = "MFM")
data %>%
mutate(category = str_replace(test22, "^(.+ .+) (.+)$", "\\1"),
price_pc = str_replace(test22, "^(.+ .+) (.+)$", "\\2"))
# A tibble: 6 x 4
test22 Ticker category price_pc
<chr> <chr> <chr> <chr>
1 Current SharePrice $6.57 MFM Current SharePrice $6.57
2 Current NAV $7.11 MFM Current NAV $7.11
3 Current Premium/Discount -7.59% MFM Current Premium/Discount -7.59%
4 52WkAvg SharePrice $6.55 MFM 52WkAvg SharePrice $6.55
5 52WkAvg NAV $7.21 MFM 52WkAvg NAV $7.21
6 52WkAvg Premium/Discount -9.19% MFM 52WkAvg Premium/Discount -9.19%
库(dplyr)
图书馆(stringr)
数据%
突变(类别=str_替换(test22,“^(+++)(++)$”,“\\1”),
价格pc=str替换(test22,“^(+.+)(.+)$”,“\\2”))
#一个tibble:6x4
test22股票类别价格\u pc
1当前股价$6.57 MFM当前股价$6.57
2当前资产净值7.11美元MFM当前资产净值7.11美元
3当前溢价/折扣-7.59%MFM当前溢价/折扣-7.59%
4 52WkAvg股价$6.55 MFM 52WkAvg股价$6.55
5 52周平均资产净值$7.21 MFM 52周平均资产净值$7.21
6 52WkAvg溢价/折扣-9.19%MFM 52WkAvg溢价/折扣-9.19%
编辑:对所用正则表达式的解释
暂时忽略括号:
^=字符串的开头
=除新行以外的任何字符
+=至少一个前一个字符(在本例中,除新行以外的任何字符)
$=字符串末尾
因此,“^(+.+)(.+)$”
查找以字符开头的字符串,然后是空格,然后是字符,然后是空格,然后是更多字符,最后是结束
括号被添加为“捕获组”,这意味着查询“记住”由这些括号表示的字符串部分,并且可以通过引用括号的顺序来提取。因此,“\\1”
返回第一个括号捕获的内容,“\\2”
返回第二个括号捕获的内容
学习正则表达式的一个好资源是。这里有一个使用dplyr
和stringr
的选项:
library(dplyr)
library(stringr)
data <-
tibble(test22 = c("Current SharePrice $6.57",
"Current NAV $7.11",
"Current Premium/Discount -7.59%",
"52WkAvg SharePrice $6.55",
"52WkAvg NAV $7.21",
"52WkAvg Premium/Discount -9.19%"),
Ticker = "MFM")
data %>%
mutate(category = str_replace(test22, "^(.+ .+) (.+)$", "\\1"),
price_pc = str_replace(test22, "^(.+ .+) (.+)$", "\\2"))
# A tibble: 6 x 4
test22 Ticker category price_pc
<chr> <chr> <chr> <chr>
1 Current SharePrice $6.57 MFM Current SharePrice $6.57
2 Current NAV $7.11 MFM Current NAV $7.11
3 Current Premium/Discount -7.59% MFM Current Premium/Discount -7.59%
4 52WkAvg SharePrice $6.55 MFM 52WkAvg SharePrice $6.55
5 52WkAvg NAV $7.21 MFM 52WkAvg NAV $7.21
6 52WkAvg Premium/Discount -9.19% MFM 52WkAvg Premium/Discount -9.19%
库(dplyr)
图书馆(stringr)
数据%
突变(类别=str_替换(test22,“^(+++)(++)$”,“\\1”),
价格pc=str替换(test22,“^(+.+)(.+)$”,“\\2”))
#一个tibble:6x4
test22股票类别价格\u pc
1当前股价$6.57 MFM当前股价$6.57
2当前资产净值7.11美元MFM当前资产净值7.11美元
3当前溢价/折扣-7.59%MFM当前溢价/折扣-7.59%
4 52WkAvg股价$6.55 MFM 52WkAvg股价$6.55
5 52周平均资产净值$7.21 MFM 52周平均资产净值$7.21
6 52WkAvg溢价/折扣-9.19%MFM 52WkAvg溢价/折扣-9.19%
编辑:对所用正则表达式的解释
暂时忽略括号:
^=字符串的开头
=除新行以外的任何字符
+=至少一个前一个字符(在本例中,除新行以外的任何字符)
$=字符串末尾
因此,“^(+.+)(.+)$”
查找以字符开头的字符串,然后是空格,然后是字符,然后是空格,然后是更多字符,最后是结束
括号被添加为“捕获组”,这意味着查询“记住”由这些括号表示的字符串部分,并且可以通过引用括号的顺序来提取。因此,“\\1”
返回第一个括号捕获的内容,“\\2”
返回第二个括号捕获的内容
学习正则表达式的一个很好的资源是。我得到了以下错误,但我将其应用于一个大数据帧:strsplit中的错误(df6$test22,“\\s(?)*\\s)”,perl=TRUE):非字符argument@js80因为你有很多因素。尝试:as.character(df$test22)
instrsplit
而不是df$test22
。或者尝试scond选项。我得到了以下错误,但我将其应用于一个大数据帧:strsplit中的错误(df6$test22,“\\s(?。*\\s)”,perl=TRUE):非字符argument@js80因为你有很多因素。尝试:as.character(df$test22)
instrsplit
而不是df$test22
。或者试试scond选项。不用担心@js80。如果你能解释一下语法:^(+.+)(.+)$”,“\\1”@js80在上面加了一个解释,因为它太冗长了,不适合评论。简而言之:它是正则表达式。不用担心@js80。如果你能解释一下语法:^(+.+)(.+)$”,“\\1”?@js80在上面添加了一个解释,因为它太罗嗦了,无法发表评论。简言之:这是正则表达式。