40

我正在寻找一个函数,它将用另一个值替换所有出现的一个值。例如,我想用一替换所有零。我不想将结果存储在变量中,但希望能够匿名使用向量作为更大表达式的一部分。

我知道如何自己编写一个合适的函数:

> vrepl <- function(haystack, needle, replacement) {
+   haystack[haystack == needle] <- replacement
+   return(haystack)
+ }
> 
> vrepl(c(3, 2, 1, 0, 4, 0), 0, 1)
[1] 3 2 1 1 4 1

但我想知道是否有一些标准功能可以完成这项工作,最好是从base包中,作为其他常用包的替代品。我相信使用这样的标准可能会使我的代码更具可读性,并且我不必在需要的地方重新定义该函数。

4

7 回答 7

79

也许replace是您正在寻找的:

> x = c(3, 2, 1, 0, 4, 0)
> replace(x, x==0, 1)
[1] 3 2 1 1 4 1

或者,如果您没有x(任何具体原因为什么没有?):

replace(c(3, 2, 1, 0, 4, 0), c(3, 2, 1, 0, 4, 0)==0, 1)

很多人都熟悉gsub,因此您也可以尝试以下任一方法:

as.numeric(gsub(0, 1, x))
as.numeric(gsub(0, 1, c(3, 2, 1, 0, 4, 0)))

更新

阅读评论后,也许with是一个选择:

with(data.frame(x = c(3, 2, 1, 0, 4, 0)), replace(x, x == 0, 1))
于 2012-07-31T10:02:25.333 回答
18

另一个更简单的选择是:

 > x = c(1, 1, 2, 4, 5, 2, 1, 3, 2)
 > x[x==1] <- 0
 > x
 [1] 0 0 2 4 5 2 0 3 2
于 2012-07-31T10:13:40.650 回答
4

一个简单的方法是使用ifelse,它是矢量化的。如果满足条件,我们使用替换值,否则使用原始值。

v <- c(3, 2, 1, 0, 4, 0)
ifelse(v == 0, 1, v)

我们可以通过使用管道来避免命名变量。

c(3, 2, 1, 0, 4, 0) %>% ifelse(. == 0, 1, .)

一个常见的任务是进行多次替换。ifelse我们可以使用case_whenfrom dplyr来代替嵌套语句:

case_when(v == 0 ~ 1,
          v == 1 ~ 2,
          TRUE ~ v)

老答案:

对于因子或字符向量,我们可以使用revaluefrom plyr

> revalue(c("a", "b", "c"), c("b" = "B"))
[1] "a" "B" "c"

这样做的好处是只指定一次输入向量,所以我们可以使用像这样的管道

x %>% revalue(c("b" = "B"))
于 2018-11-11T22:12:52.593 回答
3

要替换多个数字:

vec <- 1:10
replace(vec, vec== c(2,6), c(0,9)) #2 and 6 will be replaced by 0 and 9.

编辑:

对于连续系列,您可以这样做,vec <- c(1:10); replace(vec, vec %in% c(2,6), c(0,9))vec <- c(1:10,2,2,2); replace(vec, vec %in% c(2,6), 0)我们可以用一个值替换多个值。

于 2015-06-15T05:42:21.200 回答
3

为什么大惊小怪?

replace(haystack, haystack %in% needles, replacements)

演示:

haystack <- c("q", "w", "e", "r", "t", "y")
needles <- c("q", "w")
replacements <- c("a", "z")

replace(haystack, haystack %in% needles, replacements)
#> [1] "a" "z" "e" "r" "t" "y"
于 2019-02-27T09:25:59.770 回答
1

ifelse功能将是一种快速简便的方法。

于 2012-07-31T15:55:55.870 回答
0

如果你想一次性替换很多值,你可以使用'library(car)'。

例子

library(car)

x <- rep(1:5,3)

xr <- recode(x, '3=1; 4=2')

x
## [1] 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
xr
## [1] 1 2 1 2 5 1 2 1 2 5 1 2 1 2 5
于 2020-05-03T10:49:36.573 回答