Tengo un marco de datos como;

   Groups   Value
    G1  NA
    G1  NA
    G1  NA
    G1  23
    G2  NA
    G2  NA
    G2  NA
    G2  NA
    G2  NA
    G2  NA
    G3  34
    G3  21
    G4  NA
    G4  NA
    G5  NA
    G5  45

Y estoy buscando un código en R para obtener otro marco de datos con valores binarios (1 para al menos un Valor en el grupo fue a> = 1) y (0 para Grupos que contienen solo valores de NA)

Y obtener un nuevo datagrama como:

G1  G2  G3  G4  G5
1   0   1   0   1

Gracias por tu ayuda.

3
chippycentra 10 may. 2019 a las 17:35

4 respuestas

La mejor respuesta

Podemos usar la base R aggregate

aggregate(Value > 1~Groups, df1, any, na.rm = TRUE, na.action = na.pass)

#  Groups Value > 1
#1     G1      TRUE
#2     G2     FALSE
#3     G3      TRUE
#4     G4     FALSE
#5     G5      TRUE

Si necesita valores 1/0 en lugar de TRUE/FALSE, puede hacer

aggregate(Value~Groups, df1, function(x) 
           +(any(x > 1, na.rm = TRUE)), na.action = na.pass)

#  Groups Value
#1     G1     1
#2     G2     0
#3     G3     1
#4     G4     0
#5     G5     1
1
Ronak Shah 10 may. 2019 a las 14:48

Con dplyr, también puedes hacer:

df %>%
 group_by(Groups) %>%
 summarise(Value = as.integer(any(!is.na(Value))))

  Groups Value
  <chr>  <int>
1 G1         1
2 G2         0
3 G3         1
4 G4         0
5 G5         1

O:

df %>%
 group_by(Groups) %>%
 summarise(Value = as.integer(max(Value, na.rm = TRUE) > 0))
1
tmfmnk 10 may. 2019 a las 14:52

Al usar la condición de bucle podemos extraer el mismo

Datos

data <- data.frame (Groups =rep(c("G1","G2"), each = 4),  Value = c(NA,NA,NA,23,NA,NA,NA,NA))

Lazo

for (i in unique(data$Groups)){
  data$new_value[data$Groups==i] <- ifelse(sum(data$Value[data$Groups==i],na.rm = T)>1,1,0)
}


data1 <- unique(data[,c(1,3)])

Groups new_value
  G1         1
  G2         0
0
Arun kumar mahesh 10 may. 2019 a las 15:11

Podemos hacerlo con table de base R. Obtenga la columna 'Valor' como vector lógico (!is.na), y encuentre la tabla de frecuencias con 'Grupos', verifique si la frecuencia es mayor que 0, convierta el vector lógico a binario con as.integer o +

+(table(df1$Groups, !is.na(df1$Value))[,2] > 0)
# G1 G2 G3 G4 G5 
# 1  0  1  0  1 

O usando rowsum de base R

rowsum(+!is.na(df1$Value), df1$Groups)

NOTA: Ambos métodos anteriores son base R - No se utilizan paquetes


O usando tidyverse

library(tidyverse)
df1 %>% 
  group_by(Groups) %>%
  summarise_all(list(~ as.integer(sum(!is.na(.)) > 0)))
# A tibble: 5 x 2
#  Groups Value
#   <chr>  <int>
#1 G1         1
#2 G2         0
#3 G3         1
#4 G4         0
#5 G5         1

O con data.table

library(data.table)
setDT(df1)[, +(sum(!is.na(Value)) > 0), Groups]

Datos

df1 <- structure(list(Groups = c("G1", "G1", "G1", "G1", "G2", "G2", 
"G2", "G2", "G2", "G2", "G3", "G3", "G4", "G4", "G5", "G5"), 
    Value = c(NA, NA, NA, 23L, NA, NA, NA, NA, NA, NA, 34L, 21L, 
    NA, NA, NA, 45L)), class = "data.frame", row.names = c(NA, 
-16L))
3
akrun 10 may. 2019 a las 14:48