我在R中有一个如下的数据框架。
test <- data.frame("FRUITSTRING" = c("APPLE_PEAR_BANANA",
"TURNIP_CABBAGE_ORANGE_PEAR_BANANA",
"APPLE_CARROT_PEAR_BANANA"),
"SPLIT_CHAR" = c("PEAR","ORANGE","PEAR"))
我希望将列FRUITSTRING拆分为两列,但根据第二列SPLIT_CHAR的值将其逐行拆分。这可能吗?注意:字符串长度可以改变,分割字符的位置也可以改变,这就是为什么我想调用一个特定的字符来进行分割。
我以前使用的函数是cSplit,但是我不知道如何将这个数据帧传递到cSplit,并使用另一列的阀作为cSplit的输入。由于
1) dplyr/stsringr/tidyr将SPLIT_CHAR字符串和周围的_替换为分号,然后以分号分隔。
library(dplyr)
library(stringr)
library(tidyr)
test %>%
mutate(FRUITSTRING = str_replace(FRUITSTRING, str_c("_", SPLIT_CHAR, "_"), ";")) %>%
separate(FRUITSTRING, c("prefix", "suffix"), sep = ";")
## prefix suffix SPLIT_CHAR
## 1 APPLE BANANA PEAR
## 2 TURNIP_CABBAGE PEAR_BANANA ORANGE
## 3 APPLE_CARROT BANANA PEAR
2) Base R - transform/sub提取前缀并使用sub分别提取后缀,因为我们需要在开始时定义的sub的矢量化版本。如果要保留FRUITSTRING,则省略transform的最后一个参数。
vsub <- Vectorize(sub)
transform(test,
prefix = vsub(paste0("_", SPLIT_CHAR, "_.*"), "", FRUITSTRING),
suffix = vsub(paste0(".*_", SPLIT_CHAR, "_"), "", FRUITSTRING),
FRUITSTRING = NULL)
## SPLIT_CHAR prefix suffix
## 1 PEAR APPLE BANANA
## 2 ORANGE TURNIP_CABBAGE PEAR_BANANA
## 3 PEAR APPLE_CARROT BANANA
2)/订阅或者相同,但使用within和稍微不同的正则表达式模式,以便我们可以为sub的两个实例使用相同的正则表达式。
vsub <- Vectorize(sub)
within(test, {
pat <- paste0("(.*)_", SPLIT_CHAR, "_(.*)")
suffix <- vsub(pat, "\2", FRUITSTRING)
prefix <- vsub(pat, "\1", FRUITSTRING)
FRUITSTRING <- pat <- NULL
})
## SPLIT_CHAR prefix suffix
## 1 PEAR APPLE BANANA
## 2 ORANGE TURNIP_CABBAGE PEAR_BANANA
## 3 PEAR APPLE_CARROT BANANA
3) cSplit如(1)所示,将SPLIT_CHAR字符串和周围的_替换为分号,然后在分号上进行分割。
library(splitstackshape)
test |>
transform(FRUITSTRING =
Vectorize(sub)(paste0("_", SPLIT_CHAR, "_"), ";", FRUITSTRING)) |>
cSplit("FRUITSTRING", sep = ";", type.convert = FALSE)
## SPLIT_CHAR FRUITSTRING_1 FRUITSTRING_2
## 1: PEAR APPLE BANANA
## 2: ORANGE TURNIP_CABBAGE PEAR_BANANA
## 3: PEAR APPLE_CARROT BANANA