web-dev-qa-db-fra.com

Compter le nombre de colonnes par une condition (>) pour chaque ligne

J'essaie de déterminer pour chaque ligne d'une matrice combien de colonnes ont des valeurs supérieures à une valeur spécifiée. Je suis désolé de poser cette question simple mais je n'ai pas pu le comprendre.

J'ai extrait les valeurs maximales de température d'une pile de rasters, de plusieurs années de rasters, pour certains points spatiaux qui m'intéressent. Les données ressemblent à:

data <- cbind('1990' = c(25, 22, 35, 42, 44), '1991' = c(23, 28, 33, 40, 45), '1992' = c(20, 20, 30, 41, 43))

    1990   1991   1992
1     25     23     20
2     22     28     20
3     35     33     30
4     42     40     41
5     44     45     43

Je veux finir avec le nombre d'années pendant lesquelles la température était supérieure à 30 pour chaque emplacement, par exemple:

    yr.above   
1          0
2          0
3          2
4          3
5          3

J'ai essayé quelques choses, mais elles n'ont pas fonctionné et étaient assez illogiques (par exemple, essayer la longueur (données [1: longueur (données), qui (bla bla n'a pas de sens)), ou appliquer (données, 1, longueur (données)> 30), je sais que cela n'a pas de sens mais je suis un peu coincé.

32
Adam

Cela vous donnera le vecteur que vous recherchez:

rowSums(data > 30)

Cela fonctionnera que data soit une matrice ou un data.frame. En outre, il utilise des fonctions vectorisées, c'est donc une approche préférée par rapport à l'utilisation de apply qui est un peu plus qu'une boucle (lente) pour.

Si data est un data.frame, vous pouvez ajouter le résultat sous forme de colonne en faisant:

data$yr.above <- rowSums(data > 30)

ou si data est une matrice:

data <- cbind(data, yr.above = rowSums(data > 30))

Vous pouvez également créer un tout nouveau data.frame:

data.frame(yr.above = rowSums(data > 30))

ou une toute nouvelle matrice:

cbind(yr.above = rowSums(data > 30))
36
flodel

Le troisième argument de apply doit être une fonction. En outre, vous pouvez compter les vérités logiques avec la somme.

apply(data, 1, function(x)sum(x > 30))
6
mengeln

On peut aussi faire avec Reduce et + (en supposant qu'il n'y ait pas d'éléments NA)

 Reduce(`+`, lapply(as.data.frame(data), `>`, 30))

Cela devrait être efficace car nous ne convertissons pas en matrix.

2
akrun