按数字字模式拆分的字符串
String split on a number word pattern
我有一个如下所示的数据框:
V1 V2
peanut butter sandwich 2 slices of bread 1 tablespoon peanut butter
我想要得到的是:
V1 V2
peanut butter sandwich 2 slices of bread
peanut butter sandwich 1 tablespoon peanut butter
我尝试使用 strsplit(df$v2, " ")
拆分字符串,但我只能使用 " "
拆分。我不确定您是否可以仅在第一个数字处拆分字符串,然后将字符提取到下一个数字。
您可以按如下方式拆分字符串:
txt <- "2 slices of bread 1 tablespoon peanut butter"
strsplit(txt, " (?=\d)", perl=TRUE)[[1]]
#[1] "2 slices of bread" "1 tablespoon peanut butter"
此处使用的正则表达式正在查找 space 后跟一个数字。它使用零宽度正前瞻 (?=)
表示如果 space 后面跟着一个数字(\d
),那么它就是我们要拆分的 space 的类型在。为什么要使用零宽度先行?这是因为我们不想使用数字作为分隔字符,我们只想匹配任何 space 后跟一个数字。
要使用该想法并构建数据框,请参阅此示例:
item <- c("peanut butter sandwich", "onion carrot mix", "hash browns")
txt <- c("2 slices of bread 1 tablespoon peanut butter", "1 onion 3 carrots", "potato")
df <- data.frame(item, txt, stringsAsFactors=FALSE)
# thanks to Ananda for recommending setNames
split.strings <- setNames(strsplit(df$txt, " (?=\d)", perl=TRUE), df$item)
# alternately:
#split.strings <- strsplit(df$txt, " (?=\d)", perl=TRUE)
#names(split.strings) <- df$item
stack(split.strings)
# values ind
#1 2 slices of bread peanut butter sandwich
#2 1 tablespoon peanut butter peanut butter sandwich
#3 1 onion onion carrot mix
#4 3 carrots onion carrot mix
#5 potato hash browns
假设您正在处理类似这样的事情:
mydf <- data.frame(
V1 = c("peanut butter sandwich", "peanut butter and jam sandwich"),
V2 = c("2 slices of bread 1 tablespoon peanut butter",
"2 slices of bread 1 tablespoon peanut butter 1 tablespoon jam"))
mydf
## V1
## 1 peanut butter sandwich
## 2 peanut butter and jam sandwich
## V2
## 1 2 slices of bread 1 tablespoon peanut butter
## 2 2 slices of bread 1 tablespoon peanut butter 1 tablespoon jam
你可以先在"V2"中添加一个你不希望的分隔符,然后使用我的"splitstackshape"中的cSplit
来获取"long"数据集格式。
library(splitstackshape)
mydf$V2 <- gsub(" (\d+)", "|\1", mydf$V2)
cSplit(mydf, "V2", "|", "long")
## V1 V2
## 1: peanut butter sandwich 2 slices of bread
## 2: peanut butter sandwich 1 tablespoon peanut butter
## 3: peanut butter and jam sandwich 2 slices of bread
## 4: peanut butter and jam sandwich 1 tablespoon peanut butter
## 5: peanut butter and jam sandwich 1 tablespoon jam
以下内容不足以 post 单独作为答案,因为它们是 @Jota 方法的变体,但为了完整起见,我在这里分享它们:
strsplit
"data.table"
以内
拆分 list
会自动展平为一列....
library(data.table)
as.data.table(mydf)[, list(
V2 = unlist(strsplit(as.character(V2), '\s(?=\d)', perl=TRUE))), by = V1]
"dplyr" + "tidyr"
您可以使用 "tidyr" 中的 unnest
将列表列扩展为长格式....
library(dplyr)
library(tidyr)
mydf %>%
mutate(V2 = strsplit(as.character(V2), " (?=\d)", perl=TRUE)) %>%
unnest(V2)
我有一个如下所示的数据框:
V1 V2
peanut butter sandwich 2 slices of bread 1 tablespoon peanut butter
我想要得到的是:
V1 V2
peanut butter sandwich 2 slices of bread
peanut butter sandwich 1 tablespoon peanut butter
我尝试使用 strsplit(df$v2, " ")
拆分字符串,但我只能使用 " "
拆分。我不确定您是否可以仅在第一个数字处拆分字符串,然后将字符提取到下一个数字。
您可以按如下方式拆分字符串:
txt <- "2 slices of bread 1 tablespoon peanut butter"
strsplit(txt, " (?=\d)", perl=TRUE)[[1]]
#[1] "2 slices of bread" "1 tablespoon peanut butter"
此处使用的正则表达式正在查找 space 后跟一个数字。它使用零宽度正前瞻 (?=)
表示如果 space 后面跟着一个数字(\d
),那么它就是我们要拆分的 space 的类型在。为什么要使用零宽度先行?这是因为我们不想使用数字作为分隔字符,我们只想匹配任何 space 后跟一个数字。
要使用该想法并构建数据框,请参阅此示例:
item <- c("peanut butter sandwich", "onion carrot mix", "hash browns")
txt <- c("2 slices of bread 1 tablespoon peanut butter", "1 onion 3 carrots", "potato")
df <- data.frame(item, txt, stringsAsFactors=FALSE)
# thanks to Ananda for recommending setNames
split.strings <- setNames(strsplit(df$txt, " (?=\d)", perl=TRUE), df$item)
# alternately:
#split.strings <- strsplit(df$txt, " (?=\d)", perl=TRUE)
#names(split.strings) <- df$item
stack(split.strings)
# values ind
#1 2 slices of bread peanut butter sandwich
#2 1 tablespoon peanut butter peanut butter sandwich
#3 1 onion onion carrot mix
#4 3 carrots onion carrot mix
#5 potato hash browns
假设您正在处理类似这样的事情:
mydf <- data.frame(
V1 = c("peanut butter sandwich", "peanut butter and jam sandwich"),
V2 = c("2 slices of bread 1 tablespoon peanut butter",
"2 slices of bread 1 tablespoon peanut butter 1 tablespoon jam"))
mydf
## V1
## 1 peanut butter sandwich
## 2 peanut butter and jam sandwich
## V2
## 1 2 slices of bread 1 tablespoon peanut butter
## 2 2 slices of bread 1 tablespoon peanut butter 1 tablespoon jam
你可以先在"V2"中添加一个你不希望的分隔符,然后使用我的"splitstackshape"中的cSplit
来获取"long"数据集格式。
library(splitstackshape)
mydf$V2 <- gsub(" (\d+)", "|\1", mydf$V2)
cSplit(mydf, "V2", "|", "long")
## V1 V2
## 1: peanut butter sandwich 2 slices of bread
## 2: peanut butter sandwich 1 tablespoon peanut butter
## 3: peanut butter and jam sandwich 2 slices of bread
## 4: peanut butter and jam sandwich 1 tablespoon peanut butter
## 5: peanut butter and jam sandwich 1 tablespoon jam
以下内容不足以 post 单独作为答案,因为它们是 @Jota 方法的变体,但为了完整起见,我在这里分享它们:
strsplit
"data.table"
以内
拆分 list
会自动展平为一列....
library(data.table)
as.data.table(mydf)[, list(
V2 = unlist(strsplit(as.character(V2), '\s(?=\d)', perl=TRUE))), by = V1]
"dplyr" + "tidyr"
您可以使用 "tidyr" 中的 unnest
将列表列扩展为长格式....
library(dplyr)
library(tidyr)
mydf %>%
mutate(V2 = strsplit(as.character(V2), " (?=\d)", perl=TRUE)) %>%
unnest(V2)