2017-05-15 4 views
-1

J'ai un ensemble de données qui ressemble à ceci:Comment faire en R

groups <- c(1:20) 
A <- c(1,3,2,4,2,5,1,6,2,7,3,5,2,6,3,5,1,5,3,4) 
B <- c(3,2,4,1,5,2,4,1,3,2,6,1,4,2,5,3,7,1,4,2) 
position <- c(2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1) 
sample.data <- data.frame(groups,A,B,position) 
head(sample.data) 
     groups  A  B  position 
    1  1  1  3  2 
    2  2  3  2  1 
    3  3  2  4  2 
    4  4  4  1  1 
    5  5  2  5  2 
    6  6  5  2  1 

La colonne « position » alterne toujours entre 2 et 1. Je veux faire ce calcul R: à partir de la première rangée, si elle est en position 1, ignorez-la. Si elle commence à 2 (comme dans cet exemple), puis calculer comme suit:

  • Prendre les 2 premières valeurs de la colonne A qui sont en position 2, en faire la moyenne, puis soustraire la première valeur qui est en position 1 (dans cet exemple: (1 + 2)/2 - 3 = -1,5). Puis répétez le calcul pour l'ensemble de valeurs suivant, en utilisant la valeur de la dernière position 2 comme point de départ, c'est-à-dire que le prochain calcul sera (2 + 2)/2 - 4 = -2.
  • Donc, fondamentalement, dans cet exemple, les calculs sont effectués pour les valeurs de ces ensembles de groupes: 1-2-3, 3-4-5, 5-6-7, etc. (la dernière valeur de la précédente est la première valeur de l'ensemble de calcul suivant)
  • Répéter le calcul jusqu'à la fin. Faites aussi la même chose pour la colonne B.
  • Puisque j'ai besoin que la trame de données originale soit intacte, placez les nouvelles valeurs calculées dans une nouvelle trame de données, avec les colonnes dA et dB correspondant aux valeurs calculées des colonnes A et B, respectivement (si ce n'est pas possible, ils peuvent être créés en tant que trames de données séparées, et je les extrairai ensuite).

sortie souhaitée (de l'exemple):

dA dB 
1 -1.5 1.5 
2 -2 3.5 
3 -3.5 2.5 
4 -4.5 2.5 
5 -4.5 2.5 
6 -2.5 4 

Répondre

1
groups <- c(1:20) 
A <- c(1,3,2,4,2,5,1,6,2,7,3,5,2,6,3,5,1,5,3,4) 
B <- c(3,2,4,1,5,2,4,1,3,2,6,1,4,2,5,3,7,1,4,2) 
position <- c(2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1) 
sample.data <- data.frame(groups,A,B,position) 

start <- match(2, sample.data$position) 
twos <- seq(from = start, to = nrow(sample.data), by = 2) 

df <- 
    sapply(c("A", "B"), function(l) { 
    sapply(twos, function(i) { 
     mean(sample.data[c(i, i+2), l]) - sample.data[i+1, l] 
    }) 
    }) 

df <- setNames(as.data.frame(df), c('dA', 'dB')) 
1

Comme vos valeurs position toujours alterner entre 1 et 2, vous pouvez définir un index des lignes impaires i1 et un index des lignes paires i2, et faire vos calculs:

## In case first row has position==1, we add an increment of 1 to the indexes 
inc=0 
if(sample.data$position[1]==1) 
{inc=1} 
i1=seq(1+inc,nrow(sample.data),by=2) 
i2=seq(2+inc,nrow(sample.data),by=2) 
res=data.frame(dA=(lead(sample.data$A[i1])+sample.data$A[i1])/2-sample.data$A[i2], 
dB=(lead(sample.data$B[i1])+sample.data$B[i1])/2-sample.data$B[i2]); 

Ce retour:

dA dB 
1 -1.5 1.5 
2 -2.0 3.5 
3 -3.5 2.5 
4 -4.5 2.5 
5 -4.5 2.5 
6 -2.5 4.0 
7 -3.5 2.5 
8 -3.0 3.0 
9 -3.0 4.5 
10 NA NA 

La dernière ligne renvoie NA, vous pouvez l'enlever si vous en avez besoin.

res=na.omit(res) 
+0

je remarquai que dans votre code, l'instruction 'if' commence par "si la première position est 2". Que se passe-t-il si l'échantillon commence à la position 1? Ignorera-t-il la première rangée ou ne fonctionnera-t-elle pas? Merci –

+0

Je pensais que vous vouliez faire les calculs seulement si la première rangée contenait 2. Mais peut-être que vous voulez faire les calculs à partir de la première rangée qui contient 2, et si la première rangée contient 1, laissez inchangé, est-ce exact ? J'ai changé la réponse pour refléter cela. – Lamia

+0

oui, désolé de la confusion. Peut-être aurais-je dû dire "ignorer la première rangée", pas "ignorer". Si les données commencent à la position 1, laissez simplement cette ligne et effectuez le calcul à partir de la première rangée de la position 2 (qui est la suivante). P.S. Je n'ai pas vu les changements, avez-vous enregistré l'édition, ou êtes encore en train d'éditer? Merci –