同一 mutate() 中的多个 str_replace 函数
multiple str_replace functions within the same mutate()
我的虚拟代码:
x <- c("A", "B", "C", "D")
y <- c("<0.5", "~1", "<10", "~30")
df <- data.frame(x,y) %>%
mutate(y1 = str_replace(y, "~", ""),
y2 = as.numeric(str_replace(y1, "<", ""))/2)
基本上我想在 y 列中做的是:
- 从包含“~”的值中删除“~”
- 从包含“<”的值中删除“<”,然后将这些值减半
理想情况下,我会给出一个完整的数字列。
如何在不需要临时“y1”变量的情况下执行此步骤?我试过将两者都放入 str_replace 但似乎不起作用,或者创建了 NA。我也尝试过在 str_replace 中使用管道,但这也不起作用。注意我只希望“<”值减半。
谢谢。
我们可以通过 OR 运算符连接几个移除条件:
library(tidyverse)
df <- data.frame(x = c("A", "B", "C", "D"),
y = c("<0.5", "~1", "<10", "~30"))
df %>%
mutate(y2 = as.numeric(str_remove(y, "<|~")),
y2 = if_else(str_detect(y, '<'), 0.5 * y2, y2))
给出:
x y y2
1 A <0.5 0.25
2 B ~1 1.00
3 C <10 5.00
4 D ~30 30.00
通过覆盖 y 更新解决方案:
df %>%
mutate(y = if_else(str_detect(y, '<'), 0.5 * as.numeric(str_remove(y, "<|~")), as.numeric(str_remove(y, "<|~"))))
给出:
x y
1 A 0.25
2 B 1.00
3 C 5.00
4 D 30.00
当然,您也可以只从解决方案 1 中删除旧的 y 列并将 y2 重命名为 y。
更新:见操作评论:
library(tidyverse)
df %>%
mutate(y = ifelse(str_detect(y, "<"), parse_number(y)/2, parse_number(y)))
x y
1 A 0.25
2 B 1.00
3 C 5.00
4 D 30.00
@deschen 回答的不错。另一种方法是使用 readr
包中的 parse_number
:
library(tidyverse)
df %>%
mutate(y2 = ifelse(str_detect(y, "<"), parse_number(y)/2, parse_number(y)))
x y y2
1 A <0.5 0.25
2 B ~1 1.00
3 C <10 5.00
4 D ~30 30.00
我的虚拟代码:
x <- c("A", "B", "C", "D")
y <- c("<0.5", "~1", "<10", "~30")
df <- data.frame(x,y) %>%
mutate(y1 = str_replace(y, "~", ""),
y2 = as.numeric(str_replace(y1, "<", ""))/2)
基本上我想在 y 列中做的是:
- 从包含“~”的值中删除“~”
- 从包含“<”的值中删除“<”,然后将这些值减半
理想情况下,我会给出一个完整的数字列。
如何在不需要临时“y1”变量的情况下执行此步骤?我试过将两者都放入 str_replace 但似乎不起作用,或者创建了 NA。我也尝试过在 str_replace 中使用管道,但这也不起作用。注意我只希望“<”值减半。
谢谢。
我们可以通过 OR 运算符连接几个移除条件:
library(tidyverse)
df <- data.frame(x = c("A", "B", "C", "D"),
y = c("<0.5", "~1", "<10", "~30"))
df %>%
mutate(y2 = as.numeric(str_remove(y, "<|~")),
y2 = if_else(str_detect(y, '<'), 0.5 * y2, y2))
给出:
x y y2
1 A <0.5 0.25
2 B ~1 1.00
3 C <10 5.00
4 D ~30 30.00
通过覆盖 y 更新解决方案:
df %>%
mutate(y = if_else(str_detect(y, '<'), 0.5 * as.numeric(str_remove(y, "<|~")), as.numeric(str_remove(y, "<|~"))))
给出:
x y
1 A 0.25
2 B 1.00
3 C 5.00
4 D 30.00
当然,您也可以只从解决方案 1 中删除旧的 y 列并将 y2 重命名为 y。
更新:见操作评论:
library(tidyverse)
df %>%
mutate(y = ifelse(str_detect(y, "<"), parse_number(y)/2, parse_number(y)))
x y
1 A 0.25
2 B 1.00
3 C 5.00
4 D 30.00
@deschen 回答的不错。另一种方法是使用 readr
包中的 parse_number
:
library(tidyverse)
df %>%
mutate(y2 = ifelse(str_detect(y, "<"), parse_number(y)/2, parse_number(y)))
x y y2
1 A <0.5 0.25
2 B ~1 1.00
3 C <10 5.00
4 D ~30 30.00