web-dev-qa-db-ja.com

ifelseはRで何もしません

私は非常に初心者のRプログラマーであり、古いSASコードをRに変換しようとしています。条件に基づいて値を置き換える必要があり、条件が偽の場合はそのままにしておきます私はこれをグーグルで検索し、投稿された多くのソリューションを試しましたが、役に立ちませんでした。これを行う理由は、イベントの最初のインスタンス(この場合は医師が処方箋を書く)を分類するためです。処方箋は昨年の5月で、最初の月(newwriter)は5です。6月であれば、6などです。今年の6月から逆戻りしているので、最初の月(newwriter )以前の処方箋が見つかった場合。以前の処方箋が見つからなかった場合、番号をそのままにしておきますこれは私が使用しているコードです:

newwriters$newwriter=ifelse(newwriters$MTRx_06_30_2017>0,18,NULL)
newwriters$newwriter=ifelse(newwriters$MTRx_05_31_2017>0,17,NULL)
newwriters$newwriter=ifelse(newwriters$MTRx_04_30_2017>0,16,NULL)
newwriters$newwriter=ifelse(newwriters$MTRx_03_31_2017>0,15,NULL)
newwriters$newwriter=ifelse(newwriters$MTRx_02_28_2017>0,14,NULL)
newwriters$newwriter=ifelse(newwriters$MTRx_01_31_2017>0,13,NULL)
newwriters$newwriter=ifelse(newwriters$MTRx_12_31_2016>0,12,NULL)
newwriters$newwriter=ifelse(newwriters$MTRx_11_30_2016>0,11,NULL)
newwriters$newwriter=ifelse(newwriters$MTRx_10_31_2016>0,10,NULL)

問題は、その月に処方箋が見つからない場合、より高い値を0に変更し続けることです。値をそのままにしておきたいです。次のすべてを試してみましたが、成功しませんでした。

newwriters$newwriter=ifelse(newwriters$MTRx_06_30_2017>0,18,newwriters$newwriter)
newwriters$newwriter=ifelse(newwriters$MTRx_06_30_2017>0,18,newwriters[,16])
newwriters$newwriter=ifelse(newwriters$MTRx_06_30_2017>0,18,)

前述したように、Rコードを書くのは初めてです。これを行うためのより良い/より速い/より効率的な方法があると確信していますが、他に何を試すべきか分かりません。よろしくお願いします!

8
Kevin.C

条件付きで列(またはベクトル)を変更し、条件が満たされていない場所にエントリをそのまま残したい場合は、ifelseなしで行うこともできます。

次の2つのベクトルを検討してください。

a = c(1,2,3,4,5)
b = c(1,1,1,1,1)

ここで、bの値が2より大きい場合、aの値を3に置き換えたいとします。目的を達成する2つの方法を次に示します。

b[a>2] = 2
b = ifelse(a>3,2,b)

両方ともb1 1 2 2 2になります。ただし、ここでは、aの値の1つをNAに置き換えてみましょう。

a = c(1,2,NA,4,5)

次に、次の2つのスニペットの結果を比較します。

b = c(1,1,1,1,1)
b[a>2] = 2
# 1 1 1 2 2

そして

b = c(1,1,1,1,1)
b = ifelse(a>3,2,b)
# 1  1 NA  2  2

これの直感的な理由は、NA>3TRUEまたはFALSEではなく、NAを返すため、ifelseは2つのフィールドのどちらを認識しないかです。戻ります。 b[a>2]を実行するときは、a>2TRUEである値のみを置換し、NATRUEではないため、3番目のエントリの値は単に変更されません。


あなたの特定のケースでは、

writers$newwriter=ifelse(newwriters$MTRx_06_30_2017>0,18,newwriters$newwriter)

これらの列にNULL値またはNA値があるため、おそらく期待どおりに機能しません。 ifelseを使用する場合は、次のようなことができます。

writers$newwriter=ifelse(newwriters$MTRx_06_30_2017>0 & !is.na(newwriters$MTRx_06_30_2017),18,newwriters$newwriter)

しかし、あなたもすることを検討するかもしれません

writers$newwriter[newwriters$MTRx_06_30_2017>0] = 18

お役に立てれば!

5
Florian

パッケージdplyrif_elseを使用する方が良いです。 NAsを明示的に処理することで、より堅牢になり、わずかに高速になります。

簡単な例:

> library(tidyverse)
> iris2 = iris %>% as_data_frame()
> 
> #add some NA's
> iris2$Sepal.Length[c(1, 5, 8)] = NA
> 
> #print
> iris2
# A tibble: 150 x 5
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
          <dbl>       <dbl>        <dbl>       <dbl> <fct>  
 1        NA           3.50         1.40       0.200 setosa 
 2         4.90        3.00         1.40       0.200 setosa 
 3         4.70        3.20         1.30       0.200 setosa 
 4         4.60        3.10         1.50       0.200 setosa 
 5        NA           3.60         1.40       0.200 setosa 
 6         5.40        3.90         1.70       0.400 setosa 
 7         4.60        3.40         1.40       0.300 setosa 
 8        NA           3.40         1.50       0.200 setosa 
 9         4.40        2.90         1.40       0.200 setosa 
10         4.90        3.10         1.50       0.100 setosa 
# ... with 140 more rows
> 
> #conditionally change
> iris2$new_var = if_else(iris2$Sepal.Length > 5, true = 100, false = 0, missing = -100)
> 
> iris2$new_var
  [1] -100    0    0    0 -100  100    0 -100    0    0  100    0    0    0  100  100  100  100  100  100  100  100    0  100    0    0    0
 [28]  100  100    0    0  100  100  100    0    0  100    0    0  100    0    0    0    0  100    0  100    0  100    0  100  100  100  100
 [55]  100  100  100    0  100  100    0  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100
 [82]  100  100  100  100  100  100  100  100  100  100  100  100    0  100  100  100  100  100  100  100  100  100  100  100  100    0  100
[109]  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100
[136]  100  100  100  100  100  100  100  100  100  100  100  100  100  100  100

そこで、5を超える値が100に、5を下回る値が0に、NAが-100に変わる新しい変数を作成しました。

2
Deleet