2015-08-22 4 views
5

Sentitevi liberi di modificare questo titolo per renderlo più comprensibile/generalizzabile ...data.table: Mark prima/dopo verificarsi del simbolo all'interno dei gruppi

Ho un oggetto data.table con 3 colonne che formano gruppi (id, id2pol_loc). All'interno di questi gruppi ci sono osservazioni di riga e ci sarà un asterisco in una riga per ogni gruppo o uno NA. Mi piacerebbe creare in modo efficiente una colonna di indicatori per ogni gruppo della riga rispetto agli asterischi (prima - 1, dopo - 0). Ecco ciò che la tabella di dati si presenta come:

id id2 pol_loc non_pol cluster_tag 
1: 1 1  3  do   NA 
2: 1 1  3  you   NA 
3: 1 1  3  *   NA 
4: 1 1  3  it   NA 
------------------------------------- 
5: 1 2  3  but   4 
6: 1 2  3  i   NA 
7: 1 2  3  *   NA 
8: 1 2  3 really   2 
9: 1 2  3  bad   NA 
------------------------------------- 
10: 1 2  5  but   4 
11: 1 2  5  i   NA 
12: 1 2  5 hate   NA 
13: 1 2  5 really   2 
14: 1 2  5  *   NA 
15: 1 2  5 dogs   NA 
------------------------------------- 
16: 2 1  4  i   NA 
17: 2 1  4  am   NA 
18: 2 1  4  the   NA 
19: 2 1  4  *   NA 
20: 2 1  4 friend   NA 
------------------------------------- 
21: 3 1  4  do   NA 
22: 3 1  4  you   NA 
23: 3 1  4 really   2 
24: 3 1  4  *   NA 
------------------------------------- 
25: 3 2  NA  NA   NA 
    id id2 pol_loc non_pol cluster_tag 

output desiderato:

Ecco l'output desiderato:

id id2 pol_loc non_pol cluster_tag before 
1: 1 1  3  do   NA  1 
2: 1 1  3  you   NA  1 
3: 1 1  3  *   NA  NA 
4: 1 1  3  it   NA  0 
---------------------------------------------- 
5: 1 2  3  but   4  1 
6: 1 2  3  i   NA  1 
7: 1 2  3  *   NA  NA 
8: 1 2  3 really   2  0 
9: 1 2  3  bad   NA  0 
---------------------------------------------- 
10: 1 2  5  but   4  1 
11: 1 2  5  i   NA  1 
12: 1 2  5 hate   NA  1 
13: 1 2  5 really   2  1 
14: 1 2  5  *   NA  NA 
15: 1 2  5 dogs   NA  0 
---------------------------------------------- 
16: 2 1  4  i   NA  1 
17: 2 1  4  am   NA  1 
18: 2 1  4  the   NA  1 
19: 2 1  4  *   NA  NA 
20: 2 1  4 friend   NA  0 
---------------------------------------------- 
21: 3 1  4  do   NA  1 
22: 3 1  4  you   NA  1 
23: 3 1  4 really   2  1 
24: 3 1  4  *   NA  NA 
---------------------------------------------- 
25: 3 2  NA  NA   NA  NA 
    id id2 pol_loc non_pol cluster_tag before 

MWE

dat <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L), 
    id2 = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L), pol_loc = c(3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 5L, 5L, 5L, 5L, 5L, 5L, 4L, 
    4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, NA), non_pol = c("do", "you", 
    "*", "it", "but", "i", "*", "really", "bad", "but", "i", 
    "hate", "really", "*", "dogs", "i", "am", "the", "*", "friend", 
    "do", "you", "really", "*", NA), cluster_tag = c(NA, NA, 
    NA, NA, "4", NA, NA, "2", NA, "4", NA, NA, "2", NA, NA, NA, 
    NA, NA, NA, NA, NA, NA, "2", NA, NA)), row.names = c(NA, 
-25L), class = "data.frame", .Names = c("id", "id2", "pol_loc", 
"non_pol", "cluster_tag")) 

library(data.table) 

setDT(dat) 

EDIT Se rende più facile o più efficiente il NA s può diventare 0 o 1 Non fa differenza e immagino sia più efficiente.

risposta

5

Prova

dat[, before:=1-cumsum(non_pol=="*"), by=.(id, id2, pol_loc)][non_pol=="*", before:=NA,] 
+0

Questo è molto meglio. – akrun

+1

Bello semplice ma non avrei pensato di seguire questa strada. Eccezionale. –

+0

'1-cumsum' mi sembra strano per aver creato un 0/1 di vars. Vorrei andare con 'before: = + (. I <= .I [which (non_pol ==" * ")])' o '1: .N <= which (non_pol ==" * ")' – Frank