J'ai le simple "test" de data.table suivant. Je voudrais sélectionner toutes les lignes de la ligne 3 à 8 avec X égal à "A":
library(data.table) set.seed(1) test <- data.table(X=c(rep("A",5),rep("B",5)),Y=rnorm(10),Z=rnorm(10)) test[3:8 & X == "A"] # gives the not desired output: 1: A -0.6264538 1.5117812 2: A 0.1836433 0.3898432 3: A -0.8356286 -0.6212406 4: A 1.5952808 -2.2146999 5: A 0.3295078 1.1249309 Warning message: In 3:8 & X == "A" : longer object length is not a multiple of shorter object length # desired outcome: 3: A -0.8356286 -0.62124058 4: A 1.5952808 -2.21469989 5: A 0.3295078 1.12493092
Entre la ligne 3: 8, je voudrais sélectionner uniquement celles avec X == " UNE". Comment est-ce possible? Veuillez noter que l'utilisation de test [3: 8] [X == "A"]
ne semble pas être une option, car je souhaite effectuer des calculs sur ces lignes qui sont enregistrées dans la table de données d'origine.
3 Réponses :
Ici 3: 8
n'est certainement pas de la même longueur que la deuxième expression ( X == "A"
) et plus encore, nous comparons un index logique avec un index numérique. Au lieu de cela, convertissez la première expression en logique en utilisant % in%
sur la séquence de lignes, puis deux choses se produisent - 1) les longueurs deviennent identiques, 2) Même type
test[(seq_len(.N) %in% 3:8) & X == "A"] # X Y Z #1: A -0.8356286 -0.6212406 #2: A 1.5952808 -2.2146999 #3: A 0.3295078 1.1249309
merci je m'attendais à ce que ce soit une seule ligne. Une manière intéressante de travailler avec .N
!
@IceCreamToucan Pas de problème. J'étais à propos de l'édition, mais il y a une autre solution publiée
library(data.table) set.seed(1) test <- data.table(X=c(rep("A",5),rep("B",5)),Y=rnorm(10),Z=rnorm(10)) test[test[, .I %in% 3:8 & X == "A"], Z := Z+3][] #> X Y Z #> 1: A -0.6264538 1.51178117 #> 2: A 0.1836433 0.38984324 #> 3: A -0.8356286 2.37875942 #> 4: A 1.5952808 0.78530011 #> 5: A 0.3295078 4.12493092 #> 6: B -0.8204684 -0.04493361 #> 7: B 0.4874291 -0.01619026 #> 8: B 0.7383247 0.94383621 #> 9: B 0.5757814 0.82122120 #> 10: B -0.3053884 0.59390132 Created on 2019-06-21 by the reprex package (v0.3.0)
Merci @ M-M. J'ai accepté la réponse d'Akrun qui était un peu plus rapide
@ Talik3233 pas de soucis, c'était juste hier qu'akrun et moi parlions d'eux comme étant un adversaire pour moi;)
Si vous devez sélectionner des lignes à partir d'un certain index (3: 8) puis filtrer une variable avec une certaine valeur (ici X == 'A'), vous pouvez essayer avec `dplyr package ':
library(data.table) library(dplyr) set.seed(1) test <- data.table(X=c(rep("A",5),rep("B",5)),Y=rnorm(10),Z=rnorm(10)) test %>% slice(3:8) %>% filter(X == 'A')
Pour info, OP a noté dans un commentaire qu'il souhaitait mettre à jour / muter ces lignes. (Votre message reste cependant une réponse valide à la question posée.)
test [3: 8,] [X == "A",]
@ M-M Je pensais à la même chose, mais je veux effectuer des calculs sur les autres colonnes (par exemple Y et Z), qui sont enregistrées dans le test. Cette approche crée un nouveau DT, de sorte que les calculs ne sont pas enregistrés. Essayez par exemple
test [3: 8,] [X == "A", Z: = Z + 3]