Soy muy novato R programador, y estoy tratando de convertir antiguos SAS código R. necesito reemplazar los valores en función de una condición, y si la condición es false, los dejo solos. He buscado en google esto y probado muchas de las soluciones publicado, pero fue en vano. La razón por la que estoy haciendo esto es para categorizar la primera instancia de un evento (en este caso, el médico de la escritura de una receta). si el primer mes que escribió una receta fue en Mayo del año pasado, su principio de mes(newwriter) es de 5. Si fue en junio, luego 6, etc. Estoy trabajando desde junio de este año, y quiero actualizar a su principio de mes(newwriter) si antes de la prescripción se encuentra. Si no antes de la prescripción se encuentra, quiero dejar el número solo. Este es el código que estoy usando:

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)

El problema es que se mantiene el cambio de valores superiores a 0 si no encuentra una receta en el mes. Yo quiero que acaba de dejar los valores por sí solos. He probado todos los siguientes, así como con ningún éxito:

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,)

Como mencioné, soy nuevo en la escritura de código R. Estoy seguro de que hay un mejor/más rápido/más eficiente de hacer esto, pero no estoy seguro de qué más probar. Gracias de antemano por su ayuda!

  • ¿Por qué no usar if(){} en lugar de ifelse()?
  • porque puedo obtener el vector de error si puedo usar si(){}. «En si (newwriters$MTRx_06_30_2017 > 0) { : la condición de longitud > 1 y sólo el primer elemento será utilizado
  • Y es que cuando apply ayuda.
  • Si usted repite básicamente la misma línea que a menudo su código es subóptima. Debe volver a escribir este lugar de seguir SAS tan literalmente. Probablemente usted también debe cambiar la forma de su datos. R es totalmente diferente de la SAS. PS: Usted seguramente no desea asignar NULL aquí.
  • Estoy familiarizado con apply, pero voy a hacer un poco de investigación, gracias!
  • Gracias Roland, ¿tienes alguna sugerencia de una mejor manera este código?

InformationsquelleAutor Kevin.C | 2017-07-17

2 Comentarios

  1. 5

    Si quieres cambiar una columna (o vector) de forma condicional, y dejar entradas de la virgen, donde la condición no se cumple, probablemente se podría hacer también sin ifelse.

    Considerar los siguientes vectores:

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

    Ahora, supongamos que queremos sustituir los valores en b con 2, si el valor en a es mayor que 3. Aquí hay dos maneras de lograr lo que desea:

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

    Ellos tanto en el resultado de b ser 1 1 2 2 2. Sin embargo, ahora vamos a reemplazar a uno de los valores en a, con NA, digamos;

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

    Ahora, compare los resultados de los dos siguientes fragmentos:

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

    y

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

    La razón intuitiva de esto es que NA>3devuelve no TRUE o FALSE, pero NA, así ifelse no sé cual de los dos campos para volver. Al hacer b[a>2], sólo se reemplazan los valores donde a>2 es TRUE, y desde NA no es TRUE, el valor de la tercera entrada es simplemente no se altera.


    Por lo que en su caso específico,

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

    probablemente no funciona como se espera porque no hay NULL o NA valores en las columnas. Si desea utilizar ifelse, se podría hacer algo como:

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

    pero usted también podría considerar la posibilidad de hacer

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

    Espero que esto ayude!

    • Tengo NA de los valores en las columnas. He añadido tu solución y funcionó como yo había pensado!. Podría usted decirme por qué funciona así que tengo una mejor comprensión de ir hacia adelante?
    • por supuesto. Se estaban comparando los valores de NA, para comprobar si eran mayores que un cierto valor. Intente lo siguiente en R: NA>1. Verás que no devuelve FALSO, pero devuelve NA! Así que el código no sabe qué hacer. Espero que esto haya ayudado! Por favor, considere la posibilidad de aceptar mi respuesta? Gracias!
  2. 1

    Mejor es utilizar if_else de paquete dplyr. Tiene un tratamiento explícito para NAs que lo hacen más robusto y también es ligeramente más rápido.

    Ejemplo rápido:

    > 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

    Así, hemos hecho una nueva variable, donde los valores por encima de 5 cambia a 100, por debajo del 5 a 0, y NA en -100.

Dejar respuesta

Please enter your comment!
Please enter your name here