【问题标题】:replace column values with vector in R stringr用R stringr中的向量替换列值
【发布时间】:2018-07-02 08:53:17
【问题描述】:

我正在尝试用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 = 13+4 = 24+3 = 34+4 = 44+5 = 55+5 = 5。这些是前列腺癌的 Gleason 评分和 Gleason 分级组。

有时运行一个就可以了:

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

并且不返回所需的输出。我究竟做错了什么?如您所见,还有一些 NAs 和两个值 "3""4" 与模式不匹配。我还想将NAs 更改为034 更改为1

【问题讨论】:

标签: r dplyr stringr


【解决方案1】:

其中一种方法可能是

#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")

【讨论】:

    【解决方案2】:

    解决您遇到的错误:str_replace_all 中的“全部”并不是说它将一个向量中的所有值替换为另一个向量中的所有值。相反,它更像是在 reprex 中设置一个全局标志。它适用于这样的情况:

    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",例如,您可以使用@ 987654332@。您还可以通过使用您尝试重新编码不存在的级别这一事实的因素来获得警告,并且您会获得当前因素的列表,这让您可以看到您尚未重新编码"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
    

    reprex package (v0.2.0) 于 2018 年 7 月 2 日创建。

    【讨论】:

      猜你喜欢
      • 2017-07-31
      • 2014-12-11
      • 1970-01-01
      • 2021-10-08
      • 2019-05-07
      • 2016-06-10
      • 2021-08-05
      • 2015-09-18
      • 2012-11-10
      相关资源
      最近更新 更多