ifelse在R

时间:2017-07-17 18:56:13

标签: r if-statement dataframe

我是一个非常新手的程序员,我试图将旧的SAS代码转换为R.我需要根据条件替换值,如果条件为假,请不要管它们。我已经搜索了这个并尝试了许多解决方案,但无济于事。我这样做的原因是对事件的第一个实例进行分类(在这种情况下,医生开处方)。如果他们写处方的第一个月是去年五月,他们的开始月份(新编)是5.如果是六月,那么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代码的新手。我确定有更好/更快/更有效的方法,但我不确定还有什么可以尝试。在此先感谢您的帮助!

2 个答案:

答案 0 :(得分:4)

如果要有条件地更改列(或向量),并且在不满足条件的情况下保持条目不变,则可能还没有ifelse

考虑以下两个向量:

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

现在,让我们说如果b中的值大于2,我们希望将a中的值替换为3。以下是实现目标的两种方法:

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

他们都会导致b1 1 2 2 2。但是,现在让我们用a替换NA中的一个值,让我们说吧;

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

现在,比较以下两个片段的结果:

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>3不返回TRUEFALSE,而是返回NA,因此ifelse不知道这两个字段中的哪一个回来。在执行b[a>2]时,我们只替换a>2TRUE的值,并且由于NA不是TRUE,因此第三个条目的值不会被更改

所以在你的具体情况下,

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

希望这有帮助!

答案 1 :(得分:1)

最好是使用 dplyr 包中的if_else。它对NA进行了明确的处理,使其更加强大,而且速度也稍快。

快速举例:

> 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。