J'ai un vecteur de nombres:
numbers <- c(4,23,4,23,5,43,54,56,657,67,67,435,
453,435,324,34,456,56,567,65,34,435)
Comment puis-je faire en sorte que R compte le nombre de fois qu'une valeur x apparaît dans le vecteur?
Vous pouvez simplement utiliser table()
:
> a <- table(numbers)
> a
numbers
4 5 23 34 43 54 56 65 67 324 435 453 456 567 657
2 1 2 2 1 1 2 1 2 1 3 1 1 1 1
Ensuite, vous pouvez le subdiviser:
> a[names(a)==435]
435
3
Ou convertissez-le en data.frame si vous êtes plus à l'aise avec cela:
> as.data.frame(table(numbers))
numbers Freq
1 4 2
2 5 1
3 23 2
4 34 2
...
Le moyen le plus direct est sum(numbers == x)
.
numbers == x
crée un vecteur logique qui est VRAI à chaque emplacement de x, et lorsque sum
ing, le vecteur logique est forcé en numérique, ce qui convertit VRAI en 1 et FAUX en 0.
Cependant, notez que pour les nombres à virgule flottante, il est préférable d'utiliser quelque chose comme: sum(abs(numbers - x) < 1e-6)
.
Je ferais probablement quelque chose comme ça
length(which(numbers==x))
Mais vraiment, une meilleure façon est
table(numbers)
Il existe également le package count(numbers)
from plyr
. Beaucoup plus pratique que table
à mon avis.
Ma solution préférée utilise rle
, qui renvoie une valeur (l'étiquette, x
dans votre exemple) et une longueur, représentant le nombre de fois où cette valeur est apparue dans l'ordre.
En combinant rle
avec sort
, vous disposez d'un moyen extrêmement rapide de compter le nombre de fois qu'une valeur est apparue. Cela peut être utile avec des problèmes plus complexes.
Exemple:
> numbers <- c(4,23,4,23,5,43,54,56,657,67,67,435,453,435,324,34,456,56,567,65,34,435)
> a <- rle(sort(numbers))
> a
Run Length Encoding
lengths: int [1:15] 2 1 2 2 1 1 2 1 2 1 ...
values : num [1:15] 4 5 23 34 43 54 56 65 67 324 ...
Si la valeur que vous voulez n'apparaît pas ou si vous devez la stocker pour plus tard, transformez a
en data.frame
.
> b <- data.frame(number=a$values, n=a$lengths)
> b
values n
1 4 2
2 5 1
3 23 2
4 34 2
5 43 1
6 54 1
7 56 2
8 65 1
9 67 2
10 324 1
11 435 3
12 453 1
13 456 1
14 567 1
15 657 1
Je trouve qu'il est rare que je veuille connaître la fréquence d'une valeur et non de toutes les valeurs, et rle semble être le moyen le plus rapide de compter et de toutes les stocker.
Il existe une fonction standard dans R pour cela
tabulate(numbers)
numbers <- c(4,23,4,23,5,43,54,56,657,67,67,435 453,435,324,34,456,56,567,65,34,435)
> length(grep(435, numbers))
[1] 3
> length(which(435 == numbers))
[1] 3
> require(plyr)
> df = count(numbers)
> df[df$x == 435, ]
x freq
11 435 3
> sum(435 == numbers)
[1] 3
> sum(grepl(435, numbers))
[1] 3
> sum(435 == numbers)
[1] 3
> tabulate(numbers)[435]
[1] 3
> table(numbers)['435']
435
3
> length(subset(numbers, numbers=='435'))
[1] 3
voici un moyen rapide et sale:
x <- 23
length(subset(numbers, numbers==x))
Si vous souhaitez compter le nombre de comparutions par la suite, vous pouvez utiliser la fonction sapply
:
index<-sapply(1:length(numbers),function(x)sum(numbers[1:x]==numbers[x]))
cbind(numbers, index)
Sortie:
numbers index
[1,] 4 1
[2,] 23 1
[3,] 4 2
[4,] 23 2
[5,] 5 1
[6,] 43 1
[7,] 54 1
[8,] 56 1
[9,] 657 1
[10,] 67 1
[11,] 67 2
[12,] 435 1
[13,] 453 1
[14,] 435 2
[15,] 324 1
[16,] 34 1
[17,] 456 1
[18,] 56 2
[19,] 567 1
[20,] 65 1
[21,] 34 2
[22,] 435 3
Vous pouvez changer le numéro de votre choix à la ligne suivante
length(which(numbers == 4))
Utilisation de table mais sans comparaison avec names
:
numbers <- c(4,23,4,23,5,43,54,56,657,67,67,435)
x <- 67
numbertable <- table(numbers)
numbertable[as.character(x)]
#67
# 2
table
est utile lorsque vous utilisez plusieurs fois le nombre d'éléments différents. Si vous n'avez besoin que d'un seul chef, utilisez sum(numbers == x)
Une autre manière que je trouve commode est:
numbers <- c(4,23,4,23,5,43,54,56,657,67,67,435,453,435,324,34,456,56,567,65,34,435)
(s<-summary (as.factor(numbers)))
Ceci convertit l'ensemble de données en facteur, puis summary () nous donne les totaux de contrôle (comptes des valeurs uniques).
La sortie est:
4 5 23 34 43 54 56 65 67 324 435 453 456 567 657
2 1 2 2 1 1 2 1 2 1 3 1 1 1 1
Cela peut être stocké en tant que dataframe si vous le souhaitez.
as.data.frame (cbind (Number = noms, Freq = s), stringsAsFactors = F, row.names = 1: longueur (s))
ici row.names a été utilisé pour renommer les noms de ligne . sans utiliser row.names, les noms de colonne en s sont utilisés comme noms de ligne dans le nouveau cadre de données
La sortie est:
Number Freq
1 4 2
2 5 1
3 23 2
4 34 2
5 43 1
6 54 1
7 56 2
8 65 1
9 67 2
10 324 1
11 435 3
12 453 1
13 456 1
14 567 1
15 657 1
Il y a différentes façons de compter un élément spécifique
library(plyr)
numbers =c(4,23,4,23,5,43,54,56,657,67,67,435,453,435,7,65,34,435)
print(length(which(numbers==435)))
#Sum counts number of TRUE's in a vector
print(sum(numbers==435))
print(sum(c(TRUE, FALSE, TRUE)))
#count is present in plyr library
#o/p of count is a DataFrame, freq is 1 of the columns of data frame
print(count(numbers[numbers==435]))
print(count(numbers[numbers==435])[['freq']])
Cela peut être fait avec outer
pour obtenir une métrice d'égalités suivie de rowSums
, avec une signification évidente.
Pour que les nombres et numbers
soient dans le même jeu de données, un nom data.frame est d'abord créé. Cette étape n'est pas nécessaire si vous souhaitez une entrée et une sortie séparées.
df <- data.frame(No = numbers)
df$count <- rowSums(outer(df$No, df$No, FUN = `==`))