заменить значения столбца на вектор в строке R - PullRequest
0 голосов
/ 02 июля 2018

Я пытаюсь видоизменять и заменять значения столбцов векторами в stringr. У меня есть некоторые проблемы, которые, я думаю, связаны с тем, как функция перезагружается. Я новичок в R и не могу точно понять, что я делаю неправильно.

Столбец, который я хотел бы изменить:

[1] "3+4" "3+3"  NA    "3+4"  NA   "4+3" "4+4" "4+3" "4+4" "5+4" "4+3" "4+3" "3+4" "4+3"
[15] "4"   NA    "4+3" NA    NA    "3+4" "4+5" NA    "3+4" NA    NA    "3+4" NA    "3+4"
[29] "3+4" "3+4" "3+3" "3"   NA    "3+3" "3+3" NA    "4+5" NA    "3+3" "3+4" "4+4" "3+4"
[43] "4+4" "3+3" "3+4" "3+4" NA    "4+3" "4+3" "3+3" "3+3" "3+4"

Я бы хотел изменить это значение на 3+3 = 1, 3+4 = 2, 4+3 = 3, 4+4 = 4, 4+5 = 5, 5+5 = 5. Это баллы Глисона и баллы Глисона по раку простаты.

Запуск по одному работает отлично:

mrgb_trus <- mrgb_trus %>% 
mutate(MRGGG = str_replace_all(MRGB_gleason, "3\\+4", "2"))

Добавление векторов:

mrgb_trus <- mrgb_trus %>% 
mutate(MRGGG = str_replace_all(MRGB_gleason, c("3\\+3", "3\\+4", "4\\+3", 
                                      "4\\+4", "4\\+5", "5\\+4", 
                                      "5\\+5"), c("1", "2", "3", 
                                      "4", "5", "5", "5")))                                                  

выдает предупреждение

Warning message:
In stri_replace_first_regex(string, pattern,   fix_replacement(replacement),  :
longer object length is not a multiple of shorter object length

и не возвращает желаемый результат. Что я делаю неправильно? Как вы можете видеть, есть также некоторые NA s и два значения "3" и "4", которые не соответствуют шаблону. Я также хотел бы изменить NA s на 0 и 3 и 4 на 1.

Ответы [ 2 ]

0 голосов
/ 02 июля 2018

Чтобы устранить полученную ошибку: «все» в str_replace_all не означает, что оно заменит все значения в одном векторе на все значения в другом векторе. Скорее, это больше похоже на установку глобального флага в репер. Это для таких ситуаций:

stringr::str_replace("a2bb4", "\\d", "x")
#> [1] "axbb4"
stringr::str_replace_all("a2bb4", "\\d", "x")
#> [1] "axbbx"

То, что вы хотите - это скорее перекодировать один набор значений в другой набор значений. Вот 3 tidyverse основанные способы.

#  3+3 = 1, 3+4 = 2, 4+3 = 3, 4+4 = 4, 4+5 = 5, 5+5 = 5

library(tidyverse)

x <- c("3+4", "3+3",  NA, "3+4",  NA, "4+3", "4+4", "4+3", "4+4", "5+4", "4+3", "4+3", "3+4", "4+3", "4",   NA, "4+3", NA, NA, "3+4", "4+5", NA, "3+4", NA, NA, "3+4", NA, "3+4", "3+4", "3+4", "3+3", "3",   NA, "3+3", "3+3", NA, "4+5", NA, "3+3", "3+4", "4+4", "3+4", "4+4", "3+3", "3+4", "3+4", NA, "4+3", "4+3", "3+3", "3+3", "3+4")

Сначала dplyr::recode принимает именованный вектор, где имена - это старые значения, а элементы - новые значения.

recode(x, "3+3" = "1", "3+4" = "2", "4+3" = "3", "4+4" = "4", "4+5" = "5", "5+5" = "5")
#>  [1] "2"   "1"   NA    "2"   NA    "3"   "4"   "3"   "4"   "5+4" "3"  
#> [12] "3"   "2"   "3"   "4"   NA    "3"   NA    NA    "2"   "5"   NA   
#> [23] "2"   NA    NA    "2"   NA    "2"   "2"   "2"   "1"   "3"   NA   
#> [34] "1"   "1"   NA    "5"   NA    "1"   "2"   "4"   "2"   "4"   "1"  
#> [45] "2"   "2"   NA    "3"   "3"   "1"   "1"   "2"

Мое предпочтение такой задаче стало создавать факторы, потому что я считаю эти дискретные текстовые значения уровнями. forcats позволяет легко перекодировать и манипулировать уровнями факторов. В этом случае я использую только fct_recode (который принимает старые и новые значения в обратном порядке от recode!), Но если у вас было несколько уровней, которые менялись, например, на "5", вы могли бы использовать fct_collapse. Вы также получаете предупреждение, используя факторы того факта, что вы пытались перекодировать уровень, которого нет, и вы получаете список текущих факторов, который позволяет увидеть, что вы еще не перекодировали "5+4".

fct_recode(as.factor(x), "1" = "3+3", "2" = "3+4", "3" = "4+3", "4" = "4+4", "5" = "4+5", "5" = "5+5")
#> Warning: Unknown levels in `f`: 5+5
#>  [1] 2    1    <NA> 2    <NA> 3    4    3    4    5+4  3    3    2    3   
#> [15] 4    <NA> 3    <NA> <NA> 2    5    <NA> 2    <NA> <NA> 2    <NA> 2   
#> [29] 2    2    1    3    <NA> 1    1    <NA> 5    <NA> 1    2    4    2   
#> [43] 4    1    2    2    <NA> 3    3    1    1    2   
#> Levels: 3 1 2 4 5 5+4

Третий способ, вероятно, наиболее устойчив, особенно если вам нужно вернуться к этому через месяц или передать информацию коллеге: составьте справочную таблицу и присоединитесь.

lookup <- tribble(
  ~old_val, ~new_val,
  "3+3",     "1",
  "3+4",     "2",
  "4+3",     "3",
  "4+4",     "4",
  "4+5",     "5",
  "5+5",     "5"
)
tibble(x = x) %>%
  left_join(lookup, by = c("x" = "old_val"))
#> # A tibble: 52 x 2
#>    x     new_val
#>    <chr> <chr>  
#>  1 3+4   2      
#>  2 3+3   1      
#>  3 <NA>  <NA>   
#>  4 3+4   2      
#>  5 <NA>  <NA>   
#>  6 4+3   3      
#>  7 4+4   4      
#>  8 4+3   3      
#>  9 4+4   4      
#> 10 5+4   <NA>   
#> # ... with 42 more rows

Создано в 2018-07-02 пакетом Представ (v0.2.0).

0 голосов
/ 02 июля 2018

Один из подходов может быть

#define your mapping here
lhs <- c('3+3', '3+4', '4+3', '4+4', '4+5', '5+5', '3', '4')
rhs <- c(1, 2, 3, 4, 5, 5, 1, 1)

df$col1_new <- ifelse(is.na(df$col1), 0, rhs[match(df$col1, lhs)])

, что дает

> df$col1_new
 [1]  2  1  0  2  0  3  4  3  4 NA  3  3  2  3  1  0  3  0  0  2  5  0  2  0  0  2  0  2  2  2  1  1  0  1  1  0  5
[38]  0  1  2  4  2  4  1  2  2  0  3  3  1  1  2

Обратите внимание, что в ваших данных выборки по-прежнему отсутствует определение 5+4.


Пример данных:

df <- structure(list(col1 = c("3+4", "3+3", NA, "3+4", NA, "4+3", "4+4", 
"4+3", "4+4", "5+4", "4+3", "4+3", "3+4", "4+3", "4", NA, "4+3", 
NA, NA, "3+4", "4+5", NA, "3+4", NA, NA, "3+4", NA, "3+4", "3+4", 
"3+4", "3+3", "3", NA, "3+3", "3+3", NA, "4+5", NA, "3+3", "3+4", 
"4+4", "3+4", "4+4", "3+3", "3+4", "3+4", NA, "4+3", "4+3", "3+3", 
"3+3", "3+4")), .Names = "col1", row.names = c(NA, -52L), class = "data.frame")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...