J'ai des vecteurs, disons a, b, c, d comme ci-dessous:

 a <- c(1,2,3,4)
 b <- c("L","L","F","L")
 c <- c(11,22,33,44)
 d <- c("Y", "N", "Y","Y")

Et j'essaye d'utiliser la pâte pour obtenir cette sortie (1):

paste(a,b,c,d, sep = "$", collapse = "%")
[1] "1$L$11$Y%2$L$22$N%3$F$33$Y%4$L$44$Y"

Ensuite, je le change en ceci, disons df:

df <- data.frame(a,b,c,d)

Et récupérez cette sortie (2):

paste(df, sep = "$", collapse = "%")
[1] "c(1, 2, 3, 4)%c(2, 2, 1, 2)%c(11, 22, 33, 44)%c(2, 1, 2, 2)"

Ma question est: (1) Quelqu'un peut-il m'expliquer pourquoi dans df il change ses éléments en numérique? (2) Existe-t-il un autre moyen d'utiliser df pour obtenir la sortie (1)?

3
mojek 23 mai 2018 à 04:25

4 réponses

Meilleure réponse

Vous ne pouvez pas appliquer directement paste à une trame de données pour votre cas ici, pour obtenir le résultat souhaité, vous devez appliquer paste en deux niveaux.

paste(apply(df, 1, function(x) paste(x, collapse = "$")), collapse = "%")

#[1] "1$L$11$Y%2$L$22$N%3$F$33$Y%4$L$44$Y"

Où la commande apply crée un vecteur par ligne

apply(df, 1, function(x) paste(x, collapse = "$"))
#[1] "1$L$11$Y" "2$L$22$N" "3$F$33$Y" "4$L$44$Y"

Et la prochaine commande paste les fusionne tous avec l'argument collapse comme "%".

2
Ronak Shah 23 mai 2018 à 01:33

paste exécute as.character (ou quelque chose de similaire en interne) sur ses ... arguments, déparant efficacement la liste. Jettes un coup d'oeil à

as.character(df)
# [1] "c(1, 2, 3, 4)"     "c(2, 2, 1, 2)"     "c(11, 22, 33, 44)" "c(2, 1, 2, 2)"    
deparse(df$a)
# [1] "c(1, 2, 3, 4)"

Votre code colle ces valeurs ensemble. Pour contourner ce problème, vous pouvez utiliser do.call.

do.call(paste, c(df, sep = "$", collapse = "%"))
# [1] "1$L$11$Y%2$L$22$N%3$F$33$Y%4$L$44$Y"
4
Rich Scriven 23 mai 2018 à 01:35

Voici une approche dplyr:

pull(summarise(unite(df, tmp, 1:ncol(df), sep="$"), paste(tmp, collapse="%")))

Ou:

df %>%
  unite(tmp, 1:ncol(df),sep="$") %>%
  summarise(output = paste(tmp, collapse="%")) %>%
  pull()
0
andrew_reece 23 mai 2018 à 01:39

Voici une alternative à l'approche que vous avez utilisée:

df_call <- c(df, sep="$")
paste(do.call(paste, df_call), collapse="%")

[1] "1$L$11$Y%2$L$22$N%3$F$33$Y%4$L$44$Y"

Démo

3
Tim Biegeleisen 23 mai 2018 à 01:33