Vous pouvez ajouter une colonne à vos données à l'aide de diverses techniques. Les citations ci - dessous proviennent de la section « Détails » du texte d'aide pertinente [[.data.frame
.
Les trames de données peuvent être indexées dans plusieurs modes. Lorsque [
et [[
sont utilisés avec un seul index vectoriel ( x[i]
ou x[[i]]
), ils indexent la trame de données comme s'il s'agissait d'une liste.
my.dataframe["new.col"] <- a.vector
my.dataframe[["new.col"]] <- a.vector
La méthode data.frame pour $
, traite x
comme une liste
my.dataframe$new.col <- a.vector
Quand [
et [[
sont utilisés avec deux indices ( x[i, j]
et x[[i, j]]
) ils agissent comme l'indexation d'une matrice
my.dataframe[ , "new.col"] <- a.vector
Puisque la méthode pour data.frame
suppose que si vous ne spécifiez pas si vous travaillez avec des colonnes ou des lignes, elle supposera que vous voulez dire des colonnes.
Pour votre exemple, cela devrait fonctionner:
# make some fake data
your.df <- data.frame(no = c(1:4, 1:7, 1:5), h_freq = runif(16), h_freqsq = runif(16))
# find where one appears and
from <- which(your.df$no == 1)
to <- c((from-1)[-1], nrow(your.df)) # up to which point the sequence runs
# generate a sequence (len) and based on its length, repeat a consecutive number len times
get.seq <- mapply(from, to, 1:length(from), FUN = function(x, y, z) {
len <- length(seq(from = x[1], to = y[1]))
return(rep(z, times = len))
})
# when we unlist, we get a vector
your.df$group <- unlist(get.seq)
# and append it to your original data.frame. since this is
# designating a group, it makes sense to make it a factor
your.df$group <- as.factor(your.df$group)
no h_freq h_freqsq group
1 1 0.40998238 0.06463876 1
2 2 0.98086928 0.33093795 1
3 3 0.28908651 0.74077119 1
4 4 0.10476768 0.56784786 1
5 1 0.75478995 0.60479945 2
6 2 0.26974011 0.95231761 2
7 3 0.53676266 0.74370154 2
8 4 0.99784066 0.37499294 2
9 5 0.89771767 0.83467805 2
10 6 0.05363139 0.32066178 2
11 7 0.71741529 0.84572717 2
12 1 0.10654430 0.32917711 3
13 2 0.41971959 0.87155514 3
14 3 0.32432646 0.65789294 3
15 4 0.77896780 0.27599187 3
16 5 0.06100008 0.55399326 3
Facilement: votre bloc de données est A
Ensuite, vous obtenez la colonne b.
la source
cumsum(b) -> b
le résultat soit directement ajouté en tant que colonne au bloc de données d'origine, quelque chose commeA$groups <- cumsum(b)
.cumsum(b)
vous donnera un vecteur de longueur 3, ou est-ce que je manque quelque chose?your.df
données, vous pouvez simplement faireyour.df$group = cumsum(your.df[, 1]==1)
pour obtenir votre nouvelle colonne de groupe.Si je comprends bien la question, vous voulez détecter quand le
h_no
n'augmente pas, puis incrémenter leclass
. (Je vais vous expliquer comment j'ai résolu ce problème, il y a une fonction autonome à la fin.)Travail
Nous ne nous soucions que de la
h_no
colonne pour le moment, nous pouvons donc l'extraire de la trame de données:Nous voulons détecter quand
h_no
ne monte pas, ce que nous pouvons faire en déterminant quand la différence entre les éléments successifs est soit négative, soit nulle. R fournit ladiff
fonction qui nous donne le vecteur des différences:Une fois que nous avons cela, il est simple de trouver ceux qui ne sont pas positifs:
Dans R,
TRUE
etFALSE
sont fondamentalement les mêmes que1
et0
, donc si nous obtenons la somme cumulée denonpos
, elle augmentera de 1 dans (presque) les endroits appropriés. Lacumsum
fonction (qui est fondamentalement l'opposé dediff
) peut le faire.Mais, il y a deux problèmes: les nombres sont trop petits; et, il nous manque le premier élément (il devrait y en avoir quatre dans la première classe).
Le premier problème est résolu simplement:
1+cumsum(nonpos)
. Et le second nécessite simplement d'ajouter un1
à l'avant du vecteur, puisque le premier élément est toujours en classe1
:Maintenant, nous pouvons le rattacher à notre bloc de données avec
cbind
(en utilisant laclass=
syntaxe, nous pouvons donner à la colonne l'en-class
tête):Et
data_w_classes
contient maintenant le résultat.Résultat final
Nous pouvons compresser les lignes ensemble et tout envelopper dans une fonction pour le rendre plus facile à utiliser:
Ou, puisqu'il est logique que le
class
soit un facteur:Vous utilisez l'une ou l'autre fonction comme:
(Cette méthode de résolution de ce problème est bonne car elle évite les itérations explicites, ce qui est généralement recommandé pour R, et évite de générer beaucoup de vecteurs intermédiaires et de listes, etc. Et aussi c'est plutôt chouette comment cela peut être écrit sur une seule ligne :))
la source
En plus de la réponse de Roman, quelque chose comme ça pourrait être encore plus simple. Notez que je ne l'ai pas testé car je n'ai pas accès à R pour le moment.
La fonction itère sur les valeurs dans
n_ho
et renvoie toujours la catégorie à laquelle appartient la valeur actuelle. Si une valeur de1
est détectée, nous augmentons la variable globaleindex
et continuons.la source
Je crois que l'utilisation de "cbind" est le moyen le plus simple d'ajouter une colonne à un bloc de données dans R. Ci-dessous un exemple:
la source
la source
Approche basée sur l'identification du nombre de groupes (
x
pomapply
) et de sa longueur (y
pomapply
)la source