1
votes

Comment fournir un résultat si au moins un élément est présent?

J'ai le bloc de données suivant '

   file sev category
1 510-1   F F
2 510-1   M F
3 510-2   M M
4 510-2   M M
5 510-4   F F 

Je souhaite créer une autre variable appelée category . Si au moins l'un des fichiers a un sev de F , je veux que la catégorie soit nommée F , de sorte que la colonne de catégorie souhaite ce qui suit

file<-c('510-1','510-1','510-2','510-2','510-4')
sev<-c('F','M','M','M','F')
df<-data.frame(file,sev)

Comment puis-je faire cela?


0 commentaires

4 Réponses :


2
votes

Après le regroupement, vous pouvez utiliser la fonction any dans une instruction if pour créer la nouvelle colonne.

library(data.table)
setDT(df)

df[, category := if(any(sev == 'F')) 'F' else 'M', by = file]

Ou avec des données .table (même sortie)

library(dplyr)

df %>% 
  group_by(file) %>% 
  mutate(category = if(any(sev == 'F')) 'F' else 'M')

# # A tibble: 5 x 3
# # Groups:   file [3]
#   file  sev   category
#   <fct> <fct> <chr>   
# 1 510-1 F     F       
# 2 510-1 M     F       
# 3 510-2 M     M       
# 4 510-2 M     M       
# 5 510-4 F     F      


0 commentaires

1
votes

ave semble être un simple R de base pour faire ce que la question demande. Si au moins ( any ) un sev == 'F' alors l'index pour sous-ensemble le vecteur de résultats potentiels c ('M', 'F') est égal à 2.

df$category <- ave(df$sev, df$file, FUN = function(x) c('M', 'F')[1+any(x == 'F')])
df
#   file sev category
#1 510-1   F        F
#2 510-1   M        F
#3 510-2   M        M
#4 510-2   M        M
#5 510-4   F        F


0 commentaires

0
votes

Si vous acceptez que file et sev ne soient pas des facteurs, cela fonctionne et est incroyablement rapide.

file<-c('510-1','510-1','510-2','510-2','510-4')
sev<-c('F','M','M','M','F')
df<-data.frame(file, sev, stringsAsFactors = F)
lookup = sapply(unique(df$file), FUN = function(f) ifelse(any(df[file == f, 'sev'] == 'F'), 'F', 'M'))
df$category = lookup[df$file]
df
#>    file sev category
#> 1 510-1   F        F
#> 2 510-1   M        F
#> 3 510-2   M        M
#> 4 510-2   M        M
#> 5 510-4   F        F

Créé le 03/10/2019 par le package reprex (v0.3.0) p >


0 commentaires

2
votes

Une option avec dplyr

df %>% 
   group_by(file) %>%
   mutate(category = c("F", "M")[match("F", sev, nomatch = 2)])

Ou en utilisant match

library(dplyr)
df %>% 
    group_by(file) %>%
    mutate(category = c("M", "F")[sum(sev == "F") + 1])
# A tibble: 5 x 3
# Groups:   file [3]
#  file  sev   category
#  <fct> <fct> <chr>   
#1 510-1 F     F       
#2 510-1 M     F       
#3 510-2 M     M       
#4 510-2 M     M       
#5 510-4 F     F     


0 commentaires