我正在尝试用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
和两个值"3"
和"4"
与模式不匹配。我还想将NA
更改为0
和3
,将4
更改为1
。
答案 0 :(得分:0)
其中一种方法可能是
#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")
答案 1 :(得分:0)
要解决您遇到的错误: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"
,则例如,您可以使用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
由reprex package(v0.2.0)于2018-07-02创建。