-1
votes

Comment convertir un dataframe au format long en une liste au format approprié?

J'ai un dataframe au format long suivant:

1

J'ai besoin de le convertir en une liste qui devrait ressembler à ceci:2

Dans lequel, chacun des éléments principaux de la liste serait le "No. d'instance" et ses sous-éléments doivent contenir toutes ses paires de paramètres et de valeurs correspondantes - au format "Paramètre X" = "abc" comme vous pouvez le voir dans la deuxième image, listées les unes après les autres.

Y a-t-il une fonction existante qui peut faire cela? Je n'ai pas vraiment pu en trouver. Toute aide sera grandement appréciée.

Merci.


1 commentaires

Bienvenue dans Stackoverflow. Veuillez prendre le temps de lire cet article sur lafaçon de fournir un excellent exemple de pandas ainsi que sur la façon de fournir un exemple minimal, complet et vérifiable et de réviser votre question en conséquence. Ces conseils sur la façon de poser une bonne question peuvent également être utiles.


3 Réponses :


1
votes
require(data.table)
your_dt <- data.table(your_df)

dt_long <- melt.data.table(your_dt, id.vars='Instance No.')
class(dt_long) # for debugging
dt_long[, strVal:=paste(variable,value, sep = '=')]

result_list <- list()

for (i in unique(dt_long[['Instance No.']])){
  result_list[[as.character(i)]] <- dt_long[`Instance No.`==i, strVal]
}

8 commentaires

Merci pour votre réponse. Ce qui suit est l'erreur que j'obtiens dans la quatrième ligne. Pouvez-vous s'il vous plaît aider avec ce que fait exactement cette ligne de code? Erreur dans := (strVal, paste (Parameter, Value,: Vérifiez que is.data.table (DT) == TRUE. Sinon,: = et := (...) sont définis pour être utilisés dans j, une seule fois et de manière particulière. Voir help (": =").


avez-vous exécuté la deuxième ligne? your_dt <- data.table(your_df) - il est nécessaire de le faire fonctionner


Oui je l'ai fait. Il fonctionne parfaitement bien jusqu'à la troisième ligne avec le dataframe "dt_long" en cours de création. Mais la quatrième ligne donne l'erreur comme je l'ai mentionné.


C'est étrange. Ok, essayez de lancer avec melt.data.table() au lieu de melt() ; lancez également class(dt_long) après cela (voir la réponse mise à jour) et dites-nous ce que cela donne


si cela ne fonctionne pas, nous ne serons pas en mesure de vous aider sans avoir une véritable partie de vos données. Si vous pouvez partager un fragment de votre tableau (sous forme de données , pas d'image), ce serait plus efficace. Pour obtenir un fragment reproductible (10 premières lignes), exécutez dput(your_df[1:10,]) et partagez la sortie dans votre question.


Après avoir exécuté avec melt.data.table() et exécuté la class(dt_long) j'obtiens "data.table" "data.frame" . Mais encore une fois, j'obtiens une erreur dans la même ligne que celle mentionnée précédemment. Mais je suppose que mon problème est résolu. @icj a fourni une solution ci-dessous qui donne le résultat souhaité que je recherchais. Merci beaucoup.


n'oubliez pas de cliquer sur "Accepter" sur la réponse d'icj si elle a résolu votre question


Terminé! Merci pour votre aide :)



1
votes

Une solution dplyr

$`2`
[1] "age=Middle-aged"   "workclass=Private" "education=Masters" "income=Large"     

$`3`
[1] "age=Senior"        "workclass=Private" "education=HS-grad" "occupation=Sales" 

$`5`
[1] "age=Middle-aged"   "workclass=Gov"     "education=Hs-grad"

Il devrait maintenant y avoir une liste de vecteurs formatés comme demandé.

require(dplyr)
df_original <- data.frame("Instance No." = c(3,3,3,3,5,5,5,2,2,2,2),
                      "Parameter" = c("age", "workclass", "education", "occupation", 
                                      "age", "workclass", "education", 
                                      "age", "workclass", "education", "income"),
                      "Value" = c("Senior", "Private", "HS-grad", "Sales",
                                  "Middle-aged", "Gov", "Hs-grad",
                                  "Middle-aged", "Private", "Masters", "Large"),
                      check.names = FALSE)
    
# the split function requires a factor to use as the grouping variable.
# Param_Value will be the properly formated vector
df_modified <- mutate(df_original,
                      Param_Value = paste0(Parameter, "=", Value))
# drop the parameter and value columns now that the data is contained in Param_Value
df_modified <- select(df_modified,
                      `Instance No.`,
                      Param_Value)

# there is now a list containing dataframes with rows grouped by Instance No.
list_format <- split(df_modified, 
                     df_modified$`Instance No.`)

# The Instance No. is still in each dataframe. Loop through each and strip the column.
list_simplified <- lapply(list_format, 
                          select, -`Instance No.`)

# unlist the remaining Param_Value column and drop the names.                      
list_out <- lapply(list_simplified , 
                   unlist, use.names = F)
                     

La solution data.table publiée est plus rapide, mais je pense que c'est un peu plus compréhensible.


3 commentaires

Merci pour votre réponse. J'obtiens une erreur dans la deuxième ligne de code. Il indique l' Error: Can't subset columns that don't exist. x Columns suivante Error: Can't subset columns that don't exist. x Columns 3436108600 , 8135121 , 8134395 , 66398212 , 49332 , etc. don't exist.


Ce n'est pas très utile. Quel est le nom de la fonction lançant l'erreur? Il semble que vous deviez ranger vos données. Les noms de colonne de dataframe correspondent-ils à ceux du code ici? Comment gérez-vous les valeurs NA?


Cela fonctionne parfaitement bien, comme je le voulais! Merci beaucoup! Je n'ai rien changé d'autre dans mes données.



0
votes

Juste pour référence. Voici le R base oneliner pour ce faire. df est votre dataframe.

l <- lapply(split(df, list(df["Instance No."])), 
            function(x) paste0(x$Parameter, "=", x$Value))


1 commentaires

Merci pour votre réponse. Le code est en cours d'exécution, mais j'obtiens une liste comprenant tous les numéros d'instance et un "=" à la fin. Cela ne ressemble pas vraiment à ce que je voulais. Mais cela ressemble plutôt à ceci: ("Instance No.1", "Instance No.2", "Instance No.3", .... "=")