Comment utiliser la valeur d'une colonne (par exemple, x
ci-dessous) pour sélectionner des valeurs parmi des colonnes possibles, lorsque la sélection est spécifique à chaque ligne?Sélection de colonne vectorisée
La variable x
détermine si la variable a
, b
ou c
doit être sélectionnée pour une ligne donnée. Voici un exemple simplifié; les cellules réelles ne sont pas une concaténation du nom de colonne et du numéro de ligne.
library(magrittr); requireNamespace("tibble"); requireNamespace("dplyr")
ds <- tibble::tibble(
x = c( 1 , 1 , 2 , 3 , 1),
a = c("a1", "a2", "a3", "a4", "a5"),
b = c("b1", "b2", "b3", "b4", "b5"),
c = c("c1", "c2", "c3", "c4", "c5")
)
Les colonnes souhaitées sont des valeurs sont:
# ds$y_desired <- c("a1", "a2", "b3", "c4", "a5")
# ds$column_desired <- c("a" , "a" , "b" , "c" , "a")
Bien sûr, ce qui suit ne produit pas une seule colonne, mais colonnes fives.
ds[, ds$column_desired]
Et ce qui suit produit l'erreur: Error in mutate_impl(.data, dots) : basic_string::_M_replace_aux
.
ds %>%
dplyr::rowwise() %>%
dplyr::mutate(
y = .[[column_desired]]
) %>%
dplyr::ungroup()
Si mon vrai scénario avait seulement deux ou trois choix, je serais probablement utiliser emboîtés-ifs, mais je voudrais une approche cartographique généralisée pour accueillir un plus grand nombre de conditions.
ds %>%
dplyr::mutate(
y_if_chain = ifelse(x==1, a, ifelse(x==2, b, c))
)
Idéalement, l'approche pourrait être dirigé par une table de consultation, ou un autre objet de métadonnées comme:
ds_lookup <- tibble::tribble(
~x, ~desired_column,
1L, "a",
2L, "b",
3L, "c"
)
Je suis sûr que cette question de commutation de colonne a été posée, mais je ne en trouver un qui s'applique.
Je préférerais une solution tidyverse (c'est ce que mon équipe préfère), mais je suis ouvert à tous les outils. Je ne pouvais pas comprendre comment utiliser une combinaison de apply et kimisc::vswitch.
'noms (ds) [- 1] [x ds $]' et 'paste0 (noms (ds) [- 1] [ds $ x], 1: nRow (ds))' – Khashaa
aussi alt pour la partie 2) 'df1 = as.data.frame (ds) [- 1]; df1 [cbind (seq_along (ds $ x), ds $ x)] '(imo pas besoin de paquets) – user20650
Le jeu de données réel n'a pas de cellules qui sont une concaténation du nom de la colonne et du numéro de ligne, donc le modèle propre de l'exemple ne peut pas être exploité. Je vais modifier le post pour clarifier cela. – wibeasley