R comment puis-je calculer la différence entre les lignes dans un bloc de données
Voici un exemple simple de mon problème:
> df <- data.frame(ID=1:10,Score=4*10:1)
> df
ID Score
1 1 40
2 2 36
3 3 32
4 4 28
5 5 24
6 6 20
7 7 16
8 8 12
9 9 8
10 10 4
> diff(df)
Error in r[i1] - r[-length(r):-(length(r) - lag + 1L)] :
non-numeric argument to binary operator
Quelqu'un peut me dire pourquoi cette erreur se produit?
- notez que
aPaulT
répondu à votre question et d'aider le site si vous avez sélectionné comme correcte en cliquant sur la coche. Ou l'un des autres excellentes solutions, si vous pensez que cela serait plus utile.
Vous devez vous connecter pour publier un commentaire.
diff veut une matrice ou d'un vecteur plutôt que d'un bloc de données. Essayez
head/tail
etnrow(df)
solutions, cela ne fonctionne pas sur certains types d'objets non numériques, tels que POSIXlt. (Undplyr
solution échoue également avec POSIXlt objets)diff(as.matrix)
etdata.table
sont rapide. Mais je vais probablement aller sur l'aide dehead/tail
ouseq_along
pour les années à venir.Peut-être vous cherchez quelque chose comme ceci:
Vous pouvez ajouter ou enlever des deux
data.frame
s ensemble si elles ont les mêmes dimensions. Donc, ce que nous faisons ici, c'est en soustrayant unedata.frame
qui est à côté de la première rangée (tail(df, -1)
) et un qui est absent de la dernière ligne (head(df, -1)
) et en soustrayant eux.head
avec -1 revenir tout à l'exception de la première ligne. IntelligentUne autre option à l'aide de
dplyr
serait à l'aide demutate_each
d'une boucle sur toutes les colonnes, obtenir la différence de la colonne (.
) avec lelag
de la colonne (.
) et retirer le NA élément au sommet avecna.omit()
EDIT:
Au lieu de
mutate_each
(obsolete - comme mentionné par @PatrickT) utilisationmutate_all
Ou avec
shift
dedata.table
. Convertir les données.image' à 'des données.table' (setDT(df)
), en boucle par les colonnes (lapply(.SD, ..
)) and get the difference between the column (
x) and the
gal(
majby default gives the
galas
type = "gal"`). Suppression de la première observation, c'est à dire NA élément.Parce que df fonctionne sur vecteur ou d'une matrice. Vous pouvez utiliser à appliquer la fonction à travers les colonnes de la sorte:
Il semble peu probable que vous voulez calculer l'écart en séquence Id, de sorte que vous pouvez choisir de l'appliquer sur toutes les colonnes sauf la première de la sorte:
Ou vous pouvez utiliser
data.table
(pas que ça ajoute quoi que ce soit ici, j'ai juste vraiment envie de commencer à l'utiliser!), et encore, je suis en supposant que vous ne souhaitez pas appliquerdiff
de la colonne ID:Et grâce à @AnandaMahto une syntaxe alternative qui donne plus de souplesse pour choisir les colonnes à exécuter sur pourrait être:
Ici
.SDcols = 1:2
signifie que vous voulez appliquer lediff
fonction pour les colonnes 1 et 2. Si vous avez 20 colonnes et ne veulent pas l'appliquer à l'ID que vous pourriez utiliser.SDcols=2:20
comme un exemple.Je voudrais montrer une autre façon de faire ce genre de choses, même souvent, j'ai le sentiment qu'il n'est pas apprécié de faire cela de cette manière: à l'aide de sql.
Le code semble compliqué, mais il ne l'est pas et il a un certain avantage, comme vous pouvez le voir sur les résultats:
Un avantage est que vous utilisez l'original dataframe (sans les convertir dans d'autres classes) et vous obtenez un bloc de données (mettre dans res <- ....). Un autre avantage est que vous avez toujours toutes les lignes. Et le troisième avantage est que vous pouvez facilement considérer le regroupement de facteurs. Par exemple:
L'ajout de cette, quelques années plus tard pour être complet - vous pouvez utiliser un simple
[.data.frame
subseting pour atteindre ce trop