Pregunta

Tengo una función que en el momento programado en un modelo funcional y cualquiera que desee para acelerarlo y, quizás, solucionar el problema más en el espíritu de R. Tengo un hoja.de.datos y quiero añadir una columna basada en la información que es donde cada entrada depende de dos filas. Por el momento parece que el siguiente:

faultFinging <- function(heartData){
    if(heartData$Pulse[[1]] == 0){
        Group <- 0
    }
    else{
        Group <- 1
    }
    for(i in seq(2, length(heartData$Pulse), 1)){
        if(heartData$Pulse[[i-1]] != 0 
            && heartData$Pulse[[i]] != 0
            && abs(heartData$Pulse[[i-1]] - heartData$Pulse[[i]])<20){
            Group[[i]] <- 1
        }
        else{
            if(heartData$Pulse[[i-1]] == 0 && heartData$Pulse[[i]] != 0){
                Group[[i]] <- 1
            }
            else{
                Group[[i]] <- 0
            }
        }
    }
    Pulse<-heartData$Pulse
    Time<-heartData$Time
    return(data.frame(Time,Pulse,Group))
}
¿Fue útil?

Solución

No se puede probar esto sin datos de la muestra, pero esta es la idea general. Puede evitar hacer el bucle for() por completo mediante el uso de & y | que son versiones vectorizadas de && y ||. Además, no hay necesidad de una instrucción if-else si hay un solo valor (verdadero o falso).

faultFinging <- function(heartData){
    Group <- as.numeric(c(heartData$Pulse[1] != 0,
      (heartData$Pulse[-nrow(heartData)] != 0 
        & heartData$Pulse[-1] != 0
        & abs(heartData$Pulse[-nrow(heartData)] - heartData$Pulse[-1])<20) |
      (heartData$Pulse[-nrow(heartData)] == 0 & heartData$Pulse[-1] != 0)))
    return(cbind(heartData, Group))
}

Poner as.numeric() alrededor del índice fijará TRUE a 1 y FALSE a 0.

Otros consejos

Esto se puede hacer de una manera más vector mediante la separación de su programa en dos partes: en primer lugar una función que toma dos muestras de tiempo y determina si cumplen con su especificación de impulsos:

isPulse <- function(previous, current)
{ 
  (previous != 0 & current !=0 & (abs(previous-current) < 20)) |
  (previous == 0 & current !=0)
}

Tenga en cuenta el uso de vector | en lugar de || booleano.

e invocarla, el suministro de las dos corrientes de vectores 'anterior' y 'corriente' compensado por un retardo adecuado, en su caso, 1:

delay <- 1
samples = length(heartData$pulse)

isPulse(heartData$pulse[-(samples-(1:delay))], heartData$pulse[-(1:delay)])

Vamos a probar esto en algunos datos confeccionados:

sampleData = c(1,0,1,1,4,25,2,0,25,0)
heartData = data.frame(pulse=sampleData)
result = isPulse(heartData$pulse[-(samples-(1:delay))], heartData$pulse[-(1:delay)])

Tenga en cuenta que la heartData$pulse[-(samples-(1:delay))] código recorta muestras delay desde el final, para el anterior adornos corriente, y heartData$pulse[-(1:delay)] delay muestras desde el principio, para el actuales corriente.

Si lo hace de forma manual, los resultados deben ser (usando F de falso y verdadero para T)

F,T,T,T,F,F,F,T,F

y ejecutándolo, encontramos que son:

> print(result)
FALSE  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE FALSE

éxito!

Desde desea enlazar éstas atrás como una columna en su base de datos original, se debe tener en cuenta que la nueva matriz es delay elementos más cortos que los datos originales, por lo que necesita para rellenar que al comienzo con elementos de retardo falso. Usted también puede querer convertirlo en 0,1 según sus datos:

resultPadded <- c(rep(FALSE,delay), result)
heartData$result = ifelse(resultPadded, 1, 0)

que da

> heartData
   pulse result
1      1      0
2      0      0
3      1      1
4      1      1
5      4      1
6     25      0
7      2      0
8      0      0
9     25      1
10     0      0
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top