【问题标题】:Parsing on the first instance of a set of values解析一组值的第一个实例
【发布时间】:2021-10-03 05:37:20
【问题描述】:

我在 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 的输入。 谢谢

【问题讨论】:

  • SPLIT_CHAR 会发生什么?是在最终结果中吗?如果是,在哪一边,新FRUITSTRING 的第一部分或第二部分?

标签: r parsing csplit


【解决方案1】:

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 或使用 base R。提取前缀并使用 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

2a) within/sub 或相同,但使用 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

【讨论】:

  • 非常感谢您的回答。非常感谢。
猜你喜欢
  • 2022-06-15
  • 2020-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-11
相关资源
最近更新 更多