2015-07-10 15 views
5

Sto installando un GLM utilizzando il pacchetto DESeq2 e ho la situazione in cui gli individui (RatID) sono annidati all'interno del trattamento (Dieta). L'autore del pacchetto suggerisce che gli individui vengano rivalutati da 1: N all'interno di ogni dieta (dove N è il numero di RatID all'interno di una dieta specifica) piuttosto che il loro livello ID/fattore originale (DESeq2 vignette, page 35.)Fattore di rilevanza per facilitare l'uso come fattore nidificato nel modello DESeq2 in R

dati simile a questa (in realtà vi sono più colonne e righe, ma omessi per semplicità):

 Diet Extraction RatID 
199 HAMSP   8 65 
74 HAMS   9 108 
308 HAMS   18 100 
41 HAMSA   3 83 
88 HAMSP   12 11 
221 HAMSP   14 66 
200 HAMSA   8 57 
155 HAMSB   1 105 
245 HAMSB   19 50 
254 HAMS   21 90 
182 HAMSB   4  4 
283 HAMSA   23 59 
180 HAMSP   4 22 
71 HAMSP   9 112 
212 HAMS   12 63 
220 HAMSP   14 54 
56 HAMS   7 81 
274 HAMSP   1 11 
114 HAMS   17 102 
143 HAMSP   22 93 

ed ecco un uscita dput() per la struttura:

data = structure(list(Diet = structure(c(4L, 1L, 1L, 2L, 4L, 4L, 2L, 
     3L, 3L, 1L, 3L, 2L, 4L, 4L, 1L, 4L, 1L, 4L, 1L, 4L), .Label = c("HAMS", 
     "HAMSA", "HAMSB", "HAMSP", "LAMS"), class = "factor"), Extraction = c(8L, 
     9L, 18L, 3L, 12L, 14L, 8L, 1L, 19L, 21L, 4L, 23L, 4L, 9L, 12L, 
     14L, 7L, 1L, 17L, 22L), RatID = structure(c(61L, 7L, 3L, 76L, 
     9L, 62L, 52L, 6L, 46L, 81L, 37L, 54L, 20L, 12L, 59L, 50L, 74L, 
     9L, 4L, 84L), .Label = c("1", "10", "100", "102", "103", "105", 
     "108", "109", "11", "110", "111", "112", "113", "13", "14", "16", 
     "17", "18", "20", "22", "23", "24", "25", "26", "27", "28", "29", 
     "3", "30", "31", "32", "34", "35", "36", "37", "39", "4", "40", 
     "42", "43", "45", "46", "48", "49", "5", "50", "51", "52", "53", 
     "54", "55", "57", "58", "59", "6", "60", "61", "62", "63", "64", 
     "65", "66", "67", "68", "69", "70", "71", "73", "77", "78", "79", 
     "8", "80", "81", "82", "83", "85", "86", "88", "89", "90", "91", 
     "92", "93", "94", "95", "96", "98", "99"), class = "factor")), .Names = c("Diet", 
     "Extraction", "RatID"), row.names = c(199L, 74L, 308L, 41L, 88L, 
     221L, 200L, 155L, 245L, 254L, 182L, 283L, 180L, 71L, 212L, 220L, 
     56L, 274L, 114L, 143L), class = "data.frame") 

può qualcuno si prega di specificare un elegante w a generare i nuovi livelli di fattore per i RatIDs all'interno di Dieta come una colonna aggiuntiva di data.frame sopra. Questa operazione può essere eseguita con la funzione roll di data.table?

uscita desiderata (fatto manualmente):

Diet Extraction RatID newCol 
1 HAMSP   8 65  1 
2 HAMS   9 108  1 
3 HAMS   18 100  2 
4 HAMSA   3 83  1 
5 HAMSP   12 11  2 
6 HAMSP   14 66  3 
7 HAMSA   8 57  2 
8 HAMSB   1 105  1 
9 HAMSB   19 50  2 
10 HAMS   21 90  3 
11 HAMSB   4  4  3 
12 HAMSA   23 59  3 
13 HAMSP   4 22  4 
14 HAMSP   9 112  5 
15 HAMS   12 63  4 
16 HAMSP   14 54  6 
17 HAMS   7 81  5 
18 HAMSP   1 11  2 
19 HAMS   17 102  6 
20 HAMSP   22 93  7 

NOTA: Non è disponibile un numero uguale di Ratti in ogni trattamento. Mi piacerebbe anche che la soluzione non riordinasse le righe nei dati (se possibile).

MODIFICA: Non esiste un ordine "naturale" per i RatID, basta che ci sia una mappatura 1: 1 all'interno di una dieta, la sua multa.

+0

Vorrei che il nuovo ID per essere da 1: N all'interno di ogni dieta, ma il suo suggerimento dà 1: N attraverso le diete. Modificherà la mia domanda per sottolineare quel bit! – Meep

+0

Non l'ho enfatizzato, ma ci sono più campioni dello stesso ratto (Rat 11 ne ha due). Quando corro sopra, Rat 11 ottiene due ID. L'ordine di RatID non deve essere conservato quando mappato ai nuovi ID. – Meep

+0

Hai ragione, errore umano lì. Risolverà. – Meep

risposta

2

È può convertire il 'RatID' in 'factor' e costringerlo a 'numerico'

library(data.table)#v1.9.4+ 
setDT(data)[, newCol:=as.numeric(factor(RatID, 
         levels=unique(RatID))), Diet] 
#  Diet Extraction RatID newCol 
# 1: HAMSP   8 65  1 
# 2: HAMS   9 108  1 
# 3: HAMS   18 100  2 
# 4: HAMSA   3 83  1 
# 5: HAMSP   12 11  2 
# 6: HAMSP   14 66  3 
# 7: HAMSA   8 57  2 
# 8: HAMSB   1 105  1 
# 9: HAMSB   19 50  2 
#10: HAMS   21 90  3 
#11: HAMSB   4  4  3 
#12: HAMSA   23 59  3 
#13: HAMSP   4 22  4 
#14: HAMSP   9 112  5 
#15: HAMS   12 63  4 
#16: HAMSP   14 54  6 
#17: HAMS   7 81  5 
#18: HAMSP   1 11  2 
#19: HAMS   17 102  6 
#20: HAMSP   22 93  7 

Oppure utilizzare match

setDT(data)[, newCol:=match(RatID, unique(RatID)), Diet] 

o simile opzione con base R

data$newCol <- with(data, ave(as.numeric(levels(RatID))[RatID], 
     Diet, FUN=function(x) match(x, unique(x)))) 
+1

Esattamente quello che voglio! Grazie: D – Meep

+1

Oops, ha alzato il voto e non ha capito che avevo bisogno di spuntare anche. Grazie! – Meep

+0

Si potrebbe trovare questo confuso, ma ho solo bisogno di generare ID per un sottoinsieme dei punti di tempo nel mio set di dati. Gli ID sono generati correttamente usando quanto sopra, ma ho notato che ci sono più livelli nel fattore rispetto ai membri 'qsd = data.table (qsd) setkey (qsd, Days) ## solo assegnare effetti annidati per i ratti all'interno della dieta trattamento, quindi i punti temporali 94,105,126,133 qsd [c ("94", "105", "126", "133"), RatIDByDiet: = as.numeric (factor (RatID, levels = unique (RatID))), per = Dieta] ' – Meep

1

Ecco la as.numeric(factor(.)) trucco implementato in dplyr:

require(dplyr) 
data %>% group_by(Diet) %>% mutate(RatIDByDiet=as.numeric(factor(RatID))) 
## Source: local data frame [20 x 4] 
## Groups: Diet 
## 
##  Diet Extraction RatID RatIDByDiet 
## 1 HAMSP   8 65   5 
## 2 HAMS   9 108   3 
## 3 HAMS   18 100   1 
## 4 HAMSA   3 83   3 
## 5 HAMSP   12 11   1 
## 6 HAMSP   14 66   6 
## 7 HAMSA   8 57   1 
## 8 HAMSB   1 105   1 
## 9 HAMSB   19 50   3 
## 10 HAMS   21 90   6 
## 11 HAMSB   4  4   2 
## 12 HAMSA   23 59   2 
## 13 HAMSP   4 22   3 
## 14 HAMSP   9 112   2 
## 15 HAMS   12 63   4 
## 16 HAMSP   14 54   4 
## 17 HAMS   7 81   5 
## 18 HAMSP   1 11   1 
## 19 HAMS   17 102   2 
## 20 HAMSP   22 93   7 

E qui è una soluzione che evita passando attraverso factor(), se si vuole più controllo su come la numerazione avviene:

data %>% group_by(Diet) %>% mutate(RatIDByDiet=match(RatID, unique(RatID))) 
## Source: local data frame [20 x 4] 
## Groups: Diet 
## 
##  Diet Extraction RatID RatIDByDiet 
## 1 HAMSP   8 65   1 
## 2 HAMS   9 108   1 
## 3 HAMS   18 100   2 
## 4 HAMSA   3 83   1 
## 5 HAMSP   12 11   2 
## 6 HAMSP   14 66   3 
## 7 HAMSA   8 57   2 
## 8 HAMSB   1 105   1 
## 9 HAMSB   19 50   2 
## 10 HAMS   21 90   3 
## 11 HAMSB   4  4   3 
## 12 HAMSA   23 59   3 
## 13 HAMSP   4 22   4 
## 14 HAMSP   9 112   5 
## 15 HAMS   12 63   4 
## 16 HAMSP   14 54   6 
## 17 HAMS   7 81   5 
## 18 HAMSP   1 11   2 
## 19 HAMS   17 102   6 
## 20 HAMSP   22 93   7 
+0

Un problema che posso vedere è che Rat 11 (ha due campioni, entrambi della stessa dieta), ma viene assegnato un ID diverso. – Meep

+0

@Meep Hai ragione. Fisso. Sto ancora cercando un modo alternativo per farlo che non richieda 'as.numeric (factor())', ma non ha ancora avuto successo. –

+0

@Meep Risolto. Dopotutto non era così difficile. --- Ah, ora vedo che Akrun aveva già quell'opzione. –