2017-07-24 2 views
0

Je voudrais faire quelque chose comme une boucle incorporée, mais en utilisant des fonctions d'application, dont le but est de vérifier diverses conditions avant de passer à la partie suivante de mon programme .en cours apply (ou variant) comme une boucle intégrée

J'ai deux objets, une liste des descriptions de produits, qui peuvent être créées comme suit:

test_products <- list(c("dingdong","small","affordable","polished"),c("wingding","medium","cheap","dull"),c("doodad","big","expensive","shiny")) 

et une trame de données de combinaisons de caractéristiques qui ne sont pas autorisés, où chaque ligne représente une combinaison refusée de fonctionnalités. Une trame de données d'échantillon peut être créé comme suit:

disallowed <- data.frame(trait1 = c("dingdong","wingding","doodad"), 
         trait2 = c("medium","big","big"), 
         stringsAsFactors = FALSE) 

Mon but est de vérifier chaque produit par rapport à chacune des combinaisons non admises de manière aussi efficace que possible. Jusqu'à présent, je peux vérifier un produit contre toutes les interdictions suivantes (dans ce cas, le troisième produit):

apply(disallowed, 1, function(x) x %in% unlist(test_products[[3]])) 

OU Je peux vérifier tous les produits contre l'une des combinaisons non admises de traits (la troisième combinaison).

lapply(test_products, function(x) disallowed[3,] %in% x) 

Est-il possible de vérifier tous les produits contre toutes les lignes de la trame de données de combinaison de fonctions non reconnues, sans utiliser une boucle?

Mon résultat final devrait ressembler à ceci:

Product 1: OK 
Product 2: OK 
Product 3: NOT OK 

Depuis Produit 3 va à l'encontre de la troisième rangée refusée.

Répondre

1

Il y a certainement des façons plus élégantes, mais je vais partager mes pensées à ce sujet.

Tout d'abord, la façon dont vous avez créé la trame de données disallowed est compliquée. J'ai décidé d'utiliser le code suivant pour créer disallowed.

# Create a data frame showing disallowed traits 
disallowed <- data.frame(trait1 = c("dingdong","wingding","doodad"), 
         trait2 = c("medium","big","big"), 
         stringsAsFactors = FALSE) 

J'ai ensuite créé une fonction appelée violate, qui a deux arguments. Le premier argument product est un vecteur de caractère. Le deuxième argument, check_df, est la trame de données contient des traits non autorisés. Le résultat de violate est un vecteur logique. TRUE signifie que les deux traits du check_df de la ligne sont tous les deux TRUE.

# Create the violate function 
violate <- function(product, check_df){ 
    temp_df <- as.data.frame(lapply(check_df, function(Col) Col %in% product)) 
    temp_vec <- apply(temp_df, 1, function(Row) sum(Row) == 2) 
    return(temp_vec) 
} 

# Test the violate function 
violate(test_products[[3]], check_df = disallowed) 
# [1] FALSE FALSE TRUE  

Après cela, j'ai appliqué la fonction violate en utilisant sapply dans la liste test_products. Les résultats de violate ont été évalués pour voir si tous les contrôles non autorisés sont FALSE

# Apply the violate function and check if all results from violate is FALSE 
sapply(test_products, function(product){ 
    sum(violate(product, check_df = disallowed)) == 0}) 
# [1] TRUE TRUE FALSE 

Comme vous pouvez le voir, le troisième élément des résultats est FALSE, ce qui indique que le troisième produit n'est pas OK, tandis que le produit 1 et produit 2 sont OK parce que les résultats finaux de sapply sont tous les deux TRUE.

+0

Merci @ycw. Tu as raison que mon exemple était compliqué! Et je vais modifier ma question pour utiliser votre modification.Va tester votre réponse plus tard aujourd'hui –

+0

Fonctionne bien! Je vous remercie. –