2010-08-23 2 views
0

Je dispose d'un cadre de données R:Créer une nouvelle colonne dans data.frame en utilisant des conditions de chaque rangée

> tab1 
    pat t conc 
1 P1 0 788 
2 P1 5 720 
3 P1 10 655 
4 P2 0 644 
5 P2 5 589 
6 P2 10 544 

Je suis en train de créer une nouvelle colonne pour conc en pourcentage de conc à t = 0 pour chaque patient. Ainsi que beaucoup d'autres choses, j'ai essayé:

tab1$conct0 <- tab1$conc/tab1$conc[tab1$t == 0 & tab1$pat == tab1$pat] 

Mais je suis clairement miles au large avec le bon code qui signifie « conc où t == 0 et pat == pat pour cette ligne particulière »

Je suis sûr que je pourrais utiliser une boucle for ou quelque chose, mais espérait qu'il y avait quelque chose de plus facile?

Merci

Répondre

1

je trouverais la concentration de départ pour chaque patient:

startConc <- tab1[tab1$t == 0,] 

qui donne (à partir de vos données par exemple)

pat t conc 
1 P1 0 788 
4 P2 0 644 

Après cela, vous pouvez utiliser apply

newconc <- apply(tab1, 1, function(x){as.numeric(x[3])/startConc[startConc$pat==x[1],3]}) 

qui vous donne

[1] 1.0000000 0.9137056 0.8312183 1.0000000 0.9145963 0.8447205 
+0

Je pense que ce n'est pas correct. Prenez un sous-ensemble de 'tab1' (par exemple:' tab1 <-subset (tab1, t <10) 'et vérifiez les résultats Le problème est avec' tab1 $ pat == unique (tab1 $ pat) ',' == 'réplique de l'opérateur vecteur plus court donc (par exemple des ensembles de données) vous comparez «1,1,1,2,2,2» avec «1,2,1,2,1,2» si accidentellement cela fonctionne.Mais si vous aviez un autre vecteur, il – Marek

+0

@Marek: Merci d'avoir repéré que Marek, j'ai corrigé le code, maintenant cela devrait fonctionner – nico

+0

Cette partie '% in%' est toujours 'TRUE' Je pense' startConc <-tab1 [tab1 $ t == 0,] '(ou' sous-ensemble (tab1, t == 0) ') est suffisant – Marek

1

Une façon un peu de fortune pour le faire, mais fonctionne dans ce cas:

xt <- xtabs(conc~t+pat,tab1) 
tab1$conct0 <- as.numeric(t(t(xt)/xt[1,])) # need to use transpose because of the way matrix vector indexing works 

Le xt[1,] représente la ligne de t=0; vous pouvez également utiliser xt["0",].

Modifier

Une façon plus robuste:

tabt <- subset(tab1,t==0) 
names(tabt)[3] <- "conct0" 
tab1 <- merge(tab1,tabt[,c(1,3)]) 
tab1$conct0 <- tab1$conc/tab1$conct0 
0

Si vous pouvez supposer que votre concentration ne dépasse pas au fil du temps, alors la réponse la plus courte et la plus rapide calcul est pour ce ...

tab1$concp <- ave(tab1$conc, tab1$pat, FUN = function(x) x/max(x)) 
+1

Cela ne fonctionnera que si' max (tab1 $ conc) 'se produit à t = 0. –

+0

Qui pourrait être réparé avec' tab1 $ conc/ave (ifelse (tab1 $ t == 0, tabule1 $ conc, -Inf), tab1 $ pat, FUN = fonction (x) max (x)) ' – Marek

2

Avec plyr:

library(plyr) 
ddply(tab1, "pat", transform, conct0 = conc/conc[t == 0]) 
1

Je voudrais utiliser tapply. Compte tenu de vos données:

tab1 <- data.frame(
    pat = c(rep("P1", 3), rep("P2", 3)), 
    t = c(0, 5, 10, 0, 5, 10), 
    conc = c(788, 720, 655, 644, 589, 544)) 

ce one-liner le fera pour vous dans la façon dont vous faites allusion à votre message:

> tab1$conc/tab1$conc[tab1$t == 0][tapply(tab1$pat, tab1$pat)] 
[1] 1.0000000 0.9137056 0.8312183 1.0000000 0.9145963 0.8447205 

Le tapply sans fonction crée un index de ligne correspondant à l'ID patient (nombre) pour chaque rangée. Je trouve cette méthode plutôt rapide et utile. Mais cela suppose que vos identifiants de patients sont commandés.Si tel est un problème, nous pouvons assurer qu'ils correspondent l'ordre id patient:

> tab1$conc/tab1$conc[tab1$t == 0][order(unique(tab1$pat))][tapply(tab1$pat, tab1$pat)] 
[1] 1.0000000 0.9137056 0.8312183 1.0000000 0.9145963 0.8447205 

Si vous utilisez ce souvent j'écrire une fonction pour elle, par exemple comme ceci:

myFract <- function(obj, x = "conc", id = "pat", time = "t", start = NULL) { 
    if (is.null(start)) start <- min(obj[, time]) 
    ii <- which(obj[, time] == start) 
    ii <- ii[order(unique(obj[, id]))][tapply(obj[, id], obj[, id])] 
    obj[, x]/obj[ii, x] 
} 

tel cela:

> myFract(tab1) 
[1] 1.0000000 0.9137056 0.8312183 1.0000000 0.9145963 0.8447205 
Questions connexes