字符串分割数据帧与向量作为 R 中的模式
String splitting a dataframe with a vector as the pattern in R
我有一个由多行组成的数据框,我想根据向量的元素将每一行分成两个部分(本质上是 运行 strsplit,向量作为 'pattern') 在 R.
数据框(只有一列)看起来像这样:
[,1]
[1,] "apple please fuji"
[2,] "pear help name"
[3,] "banana me mango"
而我的模式向量可能如下所示:v <- c("please", "help", "me")
。
如果可能,我希望我的 end 输出为:
df$name df$part1 df$split df$part2
"apple please fuji" "apple" "please" "fuji"
"pear help name" "pear" "help" "name"
"banana me mango" "banana" "me" "mango"
对于能够基于向量隔离组件的中间步骤,我将不胜感激,但如果有更简单的方法将其放入数据框中,那就太好了!非常感谢!
此解决方案假定 v
中的元素数等于数据框中的行数。您可以使用 tidyr
包中的 separate
来创建 part1
和 part2
。
library(tidyverse)
df <- tibble(name = c("apple please fuji", "pear help name", "banana me mango"))
v <- c("please", "help", "me")
df %>%
separate(name, c("part1", "part2"), v, remove = FALSE) %>%
add_column(split = v, .before = "part2")
#> # A tibble: 3 x 4
#> name part1 split part2
#> <chr> <chr> <chr> <chr>
#> 1 apple please fuji apple please fuji
#> 2 pear help name pear help name
#> 3 banana me mango banana me mango
如果您想尝试使用 v
中的 any 元素拆分每一行,那么您可以先尝试将 v
粘贴到一个模式中,然后再进行分隔.我认为这样的事情应该有效。
library(tidyverse)
library(stringr)
p <- paste0("\b(?:", paste(v, collapse = "|"), ")\b")
df %>%
separate(name, c("part1", "part2"), p, remove = FALSE) %>%
mutate(split = str_extract(name, p)) %>%
select(name, part1, split, part2)
#> # A tibble: 3 x 4
#> name part1 split part2
#> <chr> <chr> <chr> <chr>
#> 1 apple please fuji apple please fuji
#> 2 pear help name pear help name
#> 3 banana me mango banana me mango
# Creating creating the df
name <- c("apple please fuji","pear help name","banana me mango")
# as.data.frame
df <- as.data.frame(name, stringsAsFactors = F)
# Initialize empty data frame.
df_n <- data.frame()
# Loop through the original rows of the df.
for(i in 1:nrow(df)){
for(j in 1:nrow(df)){
o <- strsplit(df$name, " ")[[i]][j]
}
}
# rename and assign new df (df_n) changes to original df.
df$part1 <- df_n$V1
df$part2 <- df_n$V2
df$part3 <- df_n$V3
print(df)
这是基本 R 中的两种方法。
从字符向量开始:
text <- c("apple please fuji", "pear help name", "banana me mango")
此外,所需的变量名称(为了方便起见)
varNames <- c("name", "part1", "split", "part2")
使用 regexec
和 regmatches
作为替代方案,您还可以使用具有 regmatches
/ regexec
组合的正则表达式来构建此数据集。
首先,使用 paste
.
从 v 构建一个正则表达式
myRegex <- paste0("^(.*) +(", paste(v, collapse="|"), ") +(.*)$")
myRegex
[1] "^(.*)(please|help|me)(.*)$"
setNames(do.call(rbind.data.frame, regmatches(text, regexec(myRegex, text))), varNames)
这个returns同上
name part1 split part2
1 apple please fuji apple please fuji
2 pear help name pear help name
3 banana me mango banana me mango
使用 strsplit
和 do.call
首先,将每个元素除以v
tmp <- do.call(strsplit, list(text, split=v))
tmp
[[1]]
[1] "apple " " fuji"
[[2]]
[1] "pear " " name"
[[3]]
[1] "banana " " mango"
现在,rbind.data.frame
这些,删除第二列,returns一个data.frame cbind
拆分和命名变量,然后用[=添加名称26=].
setNames(cbind(text, do.call(rbind.data.frame, tmp), v)[c(1, 2, 4, 2)], varNames)
这个returns
name part1 split part2
1 apple please fuji apple please apple
2 pear help name pear help pear
3 banana me mango banana me banana
我有一个由多行组成的数据框,我想根据向量的元素将每一行分成两个部分(本质上是 运行 strsplit,向量作为 'pattern') 在 R.
数据框(只有一列)看起来像这样:
[,1]
[1,] "apple please fuji"
[2,] "pear help name"
[3,] "banana me mango"
而我的模式向量可能如下所示:v <- c("please", "help", "me")
。
如果可能,我希望我的 end 输出为:
df$name df$part1 df$split df$part2
"apple please fuji" "apple" "please" "fuji"
"pear help name" "pear" "help" "name"
"banana me mango" "banana" "me" "mango"
对于能够基于向量隔离组件的中间步骤,我将不胜感激,但如果有更简单的方法将其放入数据框中,那就太好了!非常感谢!
此解决方案假定 v
中的元素数等于数据框中的行数。您可以使用 tidyr
包中的 separate
来创建 part1
和 part2
。
library(tidyverse)
df <- tibble(name = c("apple please fuji", "pear help name", "banana me mango"))
v <- c("please", "help", "me")
df %>%
separate(name, c("part1", "part2"), v, remove = FALSE) %>%
add_column(split = v, .before = "part2")
#> # A tibble: 3 x 4
#> name part1 split part2
#> <chr> <chr> <chr> <chr>
#> 1 apple please fuji apple please fuji
#> 2 pear help name pear help name
#> 3 banana me mango banana me mango
如果您想尝试使用 v
中的 any 元素拆分每一行,那么您可以先尝试将 v
粘贴到一个模式中,然后再进行分隔.我认为这样的事情应该有效。
library(tidyverse)
library(stringr)
p <- paste0("\b(?:", paste(v, collapse = "|"), ")\b")
df %>%
separate(name, c("part1", "part2"), p, remove = FALSE) %>%
mutate(split = str_extract(name, p)) %>%
select(name, part1, split, part2)
#> # A tibble: 3 x 4
#> name part1 split part2
#> <chr> <chr> <chr> <chr>
#> 1 apple please fuji apple please fuji
#> 2 pear help name pear help name
#> 3 banana me mango banana me mango
# Creating creating the df
name <- c("apple please fuji","pear help name","banana me mango")
# as.data.frame
df <- as.data.frame(name, stringsAsFactors = F)
# Initialize empty data frame.
df_n <- data.frame()
# Loop through the original rows of the df.
for(i in 1:nrow(df)){
for(j in 1:nrow(df)){
o <- strsplit(df$name, " ")[[i]][j]
}
}
# rename and assign new df (df_n) changes to original df.
df$part1 <- df_n$V1
df$part2 <- df_n$V2
df$part3 <- df_n$V3
print(df)
这是基本 R 中的两种方法。
从字符向量开始:
text <- c("apple please fuji", "pear help name", "banana me mango")
此外,所需的变量名称(为了方便起见)
varNames <- c("name", "part1", "split", "part2")
使用 regexec
和 regmatches
作为替代方案,您还可以使用具有 regmatches
/ regexec
组合的正则表达式来构建此数据集。
首先,使用 paste
.
myRegex <- paste0("^(.*) +(", paste(v, collapse="|"), ") +(.*)$")
myRegex
[1] "^(.*)(please|help|me)(.*)$"
setNames(do.call(rbind.data.frame, regmatches(text, regexec(myRegex, text))), varNames)
这个returns同上
name part1 split part2
1 apple please fuji apple please fuji
2 pear help name pear help name
3 banana me mango banana me mango
使用 strsplit
和 do.call
首先,将每个元素除以v
tmp <- do.call(strsplit, list(text, split=v))
tmp
[[1]]
[1] "apple " " fuji"
[[2]]
[1] "pear " " name"
[[3]]
[1] "banana " " mango"
现在,rbind.data.frame
这些,删除第二列,returns一个data.frame cbind
拆分和命名变量,然后用[=添加名称26=].
setNames(cbind(text, do.call(rbind.data.frame, tmp), v)[c(1, 2, 4, 2)], varNames)
这个returns
name part1 split part2
1 apple please fuji apple please apple
2 pear help name pear help pear
3 banana me mango banana me banana