1. ホーム
  2. r

[解決済み】dplyrパッケージは条件付き変異に使用できますか?

2022-04-20 14:43:37

質問

突然変異が条件付き(特定の列の値の値によって)である場合に、mutateを使用することは可能ですか?

この例は、私が言いたいことを示すのに役立ちます。

structure(list(a = c(1, 3, 4, 6, 3, 2, 5, 1), b = c(1, 3, 4, 
2, 6, 7, 2, 6), c = c(6, 3, 6, 5, 3, 6, 5, 3), d = c(6, 2, 4, 
5, 3, 7, 2, 6), e = c(1, 2, 4, 5, 6, 7, 6, 3), f = c(2, 3, 4, 
2, 2, 7, 5, 2)), .Names = c("a", "b", "c", "d", "e", "f"), row.names = c(NA, 
8L), class = "data.frame")

  a b c d e f
1 1 1 6 6 1 2
2 3 3 3 2 2 3
3 4 4 6 4 4 4
4 6 2 5 5 5 2
5 3 6 3 3 6 2
6 2 7 6 7 7 7
7 5 2 5 2 6 5
8 1 6 3 6 3 2

私は新しい列gを作成するためのdplyrパッケージ(そしてはい、私はこれが動作するはずのコードではないことを知っているが、私はそれが目的を明確にすると思います)を使用して私の問題の解決策を見つけることを期待していた。

 library(dplyr)
 df <- mutate(df,
         if (a == 2 | a == 5 | a == 7 | (a == 1 & b == 4)){g = 2},
         if (a == 0 | a == 1 | a == 4 | a == 3 |  c == 4) {g = 3})

私が探しているコードの結果は、この特定の例ではこのような結果になるはずです。

  a b c d e f  g
1 1 1 6 6 1 2  3
2 3 3 3 2 2 3  3
3 4 4 6 4 4 4  3
4 6 2 5 5 5 2 NA
5 3 6 3 3 6 2 NA
6 2 7 6 7 7 7  2
7 5 2 5 2 6 5  2
8 1 6 3 6 3 2  3

どなたか、dplyrでこれを行う方法についてご存知の方はいらっしゃいませんか?このデータフレームはほんの一例で、私が扱っているデータフレームはもっと大きなものです。その速度のために、私はdplyrを使用しようとしましたが、おそらくこの問題を処理するための他のより良い方法があるのでしょうか?

どのように解決するのですか?

使用方法 ifelse

df %>%
  mutate(g = ifelse(a == 2 | a == 5 | a == 7 | (a == 1 & b == 4), 2,
               ifelse(a == 0 | a == 1 | a == 4 | a == 3 |  c == 4, 3, NA)))

追加 - if_else: なお、dplyr 0.5には if_else 関数が定義されているので、代替案として ifelseif_else ただし if_else よりも厳格である。 ifelse (条件の両足が同じ型でなければならない) ので NA に置き換える必要があります。 NA_real_ .

df %>%
  mutate(g = if_else(a == 2 | a == 5 | a == 7 | (a == 1 & b == 4), 2,
               if_else(a == 0 | a == 1 | a == 4 | a == 3 |  c == 4, 3, NA_real_)))

追加 - case_when この質問が投稿された後、dplyrは以下を追加しました。 case_when ということで、別の選択肢もあります。

df %>% mutate(g = case_when(a == 2 | a == 5 | a == 7 | (a == 1 & b == 4) ~ 2,
                            a == 0 | a == 1 | a == 4 | a == 3 |  c == 4 ~ 3,
                            TRUE ~ NA_real_))

追加 - 算術/na_if 質問のように、値が数値で、条件(最後のデフォルト値NAを除く)が相互に排他的である場合、各項が目的の結果に乗算されるような算術式を使用することができ、次のようになります。 na_if で0をNAに置き換えています。

df %>%
  mutate(g = 2 * (a == 2 | a == 5 | a == 7 | (a == 1 & b == 4)) +
             3 * (a == 0 | a == 1 | a == 4 | a == 3 |  c == 4),
         g = na_if(g, 0))