web-dev-qa-db-ja.com

ベクトル内の指定された値を置き換えます

ある値のすべての出現を別の値で置き換える関数を探しています。たとえば、すべてのゼロを1に置き換えたいです。結果を変数に保存する必要はありませんが、より大きな式の一部として匿名でベクトルを使用できるようにしたいです。

私は自分で適切な関数を書く方法を知っています:

> 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パッケージから、この仕事をするための標準機能があるかどうか疑問に思っています。このような標準を使用するとコードが読みやすくなり、必要な場所でその関数を再定義する必要がなくなると思います。

25
MvG

おそらく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))
51

別のより簡単なオプションは次のとおりです。

 > 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
14
nico

複数の番号を置き換えるには:

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)の場合、複数の値を1つの値に置き換えることができます。

4
TheMI

これを行う簡単な方法は、ベクトル化された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ステートメントの代わりに、dplyrcase_whenを使用できます。

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

古い答え:

因子または文字ベクトルの場合、revalueからplyrを使用できます。

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

これには、入力ベクトルを一度しか指定しないという利点があるため、次のようなパイプを使用できます。

x %>% revalue(c("b" = "B"))
2
qwr

なぜ大騒ぎするのですか?

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"
1
MS Berends

ifelse関数を使用すると、これをすばやく簡単に行うことができます。

1
Greg Snow