Как последовательно заменить подстроки в векторе на строки в другом в R, используя функцию map? - PullRequest
1 голос
/ 15 апреля 2019

У меня есть вектор из трехсимвольных строк, каждая из которых содержит подстроку «X»:

v<- c("kpX_43", "kpX_10", "kpX_11")

«X» - это заполнитель, который либо заполняется на «1», «2», «3 "или" a1 ".Теперь я пытаюсь заменить «X» на «1», «2», «3» и «a1».Кроме того, я должен добавить «a» и «b», что приведет к следующему вектору:

> v_new
[1] "kp1_43a" "kp1_10a" "kp1_11a" "kp2_43a" "kp2_10a" "kp2_11a" "kp3_43a" "kp3_10a" "kp3_11a" "kp1_43b" "kpa1_10a" "kpa1_11a" "kpa1_43b" "kp1_10b" "kp1_11b" "kp2_43b" "kp2_10b" "kp2_11b" "kp3_43b" "kp3_10b" "kp3_11b" "kpa1_10b" "kpa1_11b" "kpa1_43b"

Я должен сделать это, используя dyplr и purrr.

Хорошо, то, что я пробовал до сих пор, выглядит следующим образом:

strings<- as.matrix(c(seq(1:3), "a1"))

v_new <- v %>% 
  map(., ~str_c(., letters[seq(from = 1, to = 2)])) %>% 
  map(function(x) {
    str_replace_all(., "X" , strings)}) %>%
  unlist()

... что приводит к:

> v_new
 [1] "c(\"kp1_43a\", \"kp1_43b\")"   "c(\"kp2_10a\", \"kp2_10b\")"   "c(\"kp3_11a\", \"kp3_11b\")"   "c(\"kpa1_43a\", \"kpa1_43b\")"
 [5] "c(\"kp1_43a\", \"kp1_43b\")"   "c(\"kp2_10a\", \"kp2_10b\")"   "c(\"kp3_11a\", \"kp3_11b\")"   "c(\"kpa1_43a\", \"kpa1_43b\")"
 [9] "c(\"kp1_43a\", \"kp1_43b\")"   "c(\"kp2_10a\", \"kp2_10b\")"   "c(\"kp3_11a\", \"kp3_11b\")"   "c(\"kpa1_43a\", \"kpa1_43b\")"

... с несколькими предупреждениями, все читают:

Warning messages:
1: In stri_replace_all_regex(string, pattern, fix_replacement(replacement),  :argument is not an atomic vector; coercing

Итак, хотя результаты уже близки к моему желаемому результату, очевидно, что-то не так с моим кодом / моим подходом.Кто-нибудь может мне помочь?

Ответы [ 4 ]

2 голосов
/ 15 апреля 2019

Используя expand.grid , затем Вставьте :

apply(expand.grid("kp",
                  c("1", "2", "3", "a1"),
                  "_",
                  c(43, 10, 11),
                  c("a", "b")), 1, paste, collapse = "")

#  [1] "kp1_43a"  "kp2_43a"  "kp3_43a"  "kpa1_43a" "kp1_10a"  "kp2_10a" 
#  [7] "kp3_10a"  "kpa1_10a" "kp1_11a"  "kp2_11a"  "kp3_11a"  "kpa1_11a"
# [13] "kp1_43b"  "kp2_43b"  "kp3_43b"  "kpa1_43b" "kp1_10b"  "kp2_10b" 
# [19] "kp3_10b"  "kpa1_10b" "kp1_11b"  "kp2_11b"  "kp3_11b"  "kpa1_11b"

Редактировать: По предложению Маркус в комментариях:

do.call(paste0, expand.grid("kp",
                            c("1", "2", "3", "a1"),
                            "_",
                            c(43, 10, 11),
                            c("a", "b")))
2 голосов
/ 15 апреля 2019

Если вы не сильно зависите от dplyr и purrr, вы можете сделать это в базе R, используя gsub

as.vector(sapply(strings, function(x) 
  paste0(gsub("X", x, v), rep(letters[1:2], 3))))
# [1] "kp1_43a"  "kp1_10b"  "kp1_11a"  "kp1_43b"  "kp1_10a" 
# [6] "kp1_11b"  "kp2_43a"  "kp2_10b"  "kp2_11a"  "kp2_43b" 
# [11] "kp2_10a"  "kp2_11b"  "kp3_43a"  "kp3_10b"  "kp3_11a" 
# [16] "kp3_43b"  "kp3_10a"  "kp3_11b"  "kpa1_43a" "kpa1_10b"
# [21] "kpa1_11a" "kpa1_43b" "kpa1_10a" "kpa1_11b"
2 голосов
/ 15 апреля 2019
library(purrr)

v <- c("kpX_43", "kpX_10", "kpX_11")
strings <- c(1:3, "a1")
suffixes <- c("a", "b")

cross(tibble::lst(v, strings, suffixes)) %>% 
  map_chr(~ paste0(sub("X", .$strings, .$v), .$suffixes))
#>  [1] "kp1_43a"  "kp1_10a"  "kp1_11a"  "kp2_43a"  "kp2_10a"  "kp2_11a" 
#>  [7] "kp3_43a"  "kp3_10a"  "kp3_11a"  "kpa1_43a" "kpa1_10a" "kpa1_11a"
#> [13] "kp1_43b"  "kp1_10b"  "kp1_11b"  "kp2_43b"  "kp2_10b"  "kp2_11b" 
#> [19] "kp3_43b"  "kp3_10b"  "kp3_11b"  "kpa1_43b" "kpa1_10b" "kpa1_11b"

Создано в 2019-04-15 пакетом представ (v0.2.1)

1 голос
/ 15 апреля 2019

Вам нужно дополнительно map внутри последней карты, чтобы выполнить итерации по a и b и заменить X на строки

library(purrr)
v %>% map(., ~str_c(., letters[seq(from = 1, to = 2)])) %>%
      map(. %>% map(.,~str_replace_all(.,'X',strings))) %>% unlist()
      #OR map(~map(.,~str_replace_all(.,'X',strings)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...