2017-08-23 1 views
0

Je veux agréger trame de données f dans une nouvelle trame de données g de telle sorte que la colonne g$z contient une liste de toutes les valeurs de la colonne sage groupe f$z. A première vue, cela semble fonctionner:Faire des calculs sur les listes à l'intérieur de trames de données

f = data.frame(x=c(1, 1, 1, 2), y=c(4, 4, 5, 6), z=c(11, 12, 13, 14)) 
g = aggregate(z ~ x + y, f, c) 

    x y  z 
1 1 4 11, 12 
2 1 5  13 
3 2 6  14 

Maintenant, je veux faire différents calculs sur les listes dans la colonne c pour toutes les lignes de la trame de données et le résultat dans les nouvelles colonnes dans la même trame de données. Mais ça ne marche pas!

g$m = sum(g$z) 
g$n = g$z + 1 

Error in sum(g$z) : invalid 'type' (list) of argument 

Comment puis-je travailler avec des listes dans une cellule de bloc de données comme essayé ci-dessus? Ou est-ce simplement un-R-like/impossible? Si oui, quelle est la bonne approche?

MISE À JOUR

Mon objectif sous-jacent est de faire un grand nombre d'opérations par groupes sur toutes les combinaisons de X et Y dans l'ensemble de données d'origine. Quelles options ai-je pour cela dans R en général?

  1. Utilisez apply. Pro: Tout dans une table. Con: structure de table complexe, ne peut pas utiliser sum etc.
  2. pour (y), pour (x), sous-ensemble. Pro: Peut faire sum etc. directement. Con: Beaucoup de code, et peut-être lent.
  3. Travailler en parallèle avec table originale et agrégée. Pro: Peut faire sum etc. Con: La duplication de données.
  4. Autres options?
+0

'spply' pour' g $ m', comme ci-dessous. Et 'g $ n <- relist (unlist (g $ z) + 1, g $ z)' –

Répondre

2

somme et Vectorisation ne concerne pas les listes, vous pouvez simplement utiliser sapply et lapply pour la tâche:

g$m <- sapply(g$z, sum) 
g$n <- lapply(g$z, `+`, 1) 

g 
# x y  z m  n 
#1 1 4 11, 12 23 12, 13 
#2 1 5  13 13  14 
#3 2 6  14 14  15 

Ou si vous utilisez tidyverse, vous pouvez utiliser map + mutate :

g %>% mutate(m = map_dbl(z, sum), n = map(z, ~.x + 1)) 

# x y  z m  n 
#1 1 4 11, 12 23 12, 13 
#2 1 5  13 13  14 
#3 2 6  14 14  15 
+0

Utilisez 'vapply', pas' sapply'. 'vapply' renvoie toujours un vecteur du type spécifié avec des dimensions connues. 'sapply' peut renvoyer un vecteur, un tableau ou une liste, selon l'entrée. –

+1

@NathanWerth - La structure de retour dépend plus de 'FUN' que de 'X'. Comme 'sum' retournera toujours une longueur de 1 numérique,' spply' retournera toujours un vecteur atomique (fourni 'simplify = TRUE'). 'vapply' est plus rapide cependant. –

+0

Utiliser apply fonctionne! Cependant, j'ai mis à jour la question afin de réfléchir à la meilleure façon de travailler avec des données de groupe dans R en général. – forthrin