Будучи все еще довольно новым для R, я борюсь со следующей проблемой: я смотрю на несколько частиц, движущихся вдоль оси x (в действительности это в 3D, но это упрощает вопросы для нашей цели, здесь). У меня есть фрейм данных с идентификатором каждой частицы и их соответствующим положением в данный момент времени. Вот пример:
x.position1 <- c(5, NA, 4, 7, 1, NA, 2, NA, NA, 3)
x.position2 <- c(6, NA, 8, 7, 2, 1, 2, NA, NA, 1)
x.position3 <- c(6, 2, 7, 7, 4, 3, 1, NA, NA, 6)
x.position4 <- c(7, 4, 9, 7, 5, 5, 0, 0, 5, 7)
x.position5 <- c(9, 5, NA, 7, 6, NA, 2, 3, 8, 11)
particule.ID <- c(1:10)
df <- data.frame(particule.ID, x.position1, x.position2, x.position3, x.position4, x.position5)
df
particule.ID x.position1 x.position2 x.position3 x.position4 x.position5
1 1 5 6 6 7 9
2 2 NA NA 2 4 5
3 3 4 8 7 9 NA
4 4 7 7 7 7 7
5 5 1 2 4 5 6
6 6 NA 1 3 5 NA
7 7 2 2 1 0 2
8 8 NA NA NA 0 3
9 9 NA NA NA 5 8
10 10 3 1 6 7 11
Моя цель - рассчитать смещение каждой частицы в каждый момент времени i. Следовательно, это смещение xi - x1. Это недавно вычисленное смещение должно быть помещено во вновь созданный столбец.
Вот сценарий, который я первоначально написал для этого:
for (i in 1:5){ # iterate for each time point i
df$Disp <- df[,2+i-1]-df[,2] # create a new column with the calculated displacement for time point i
nam.Disp <- paste("Disp", i, sep = "") #rename new column Disp+time point number
names(df)[names(df) == 'Disp'] <- nam.Disp
}
df
particule.ID x.position1 x.position2 x.position3 x.position4 x.position5 Disp1 Disp2 Disp3 Disp4 Disp5
1 1 5 6 6 7 9 0 1 1 2 4
2 2 NA NA 2 4 5 NA NA NA NA NA
3 3 4 8 7 9 NA 0 4 3 5 NA
4 4 7 7 7 7 7 0 0 0 0 0
5 5 1 2 4 5 6 0 1 3 4 5
6 6 NA 1 3 5 NA NA NA NA NA NA
7 7 2 2 1 0 2 0 0 -1 -2 0
8 8 NA NA NA 0 3 NA NA NA NA NA
9 9 NA NA NA 5 8 NA NA NA NA NA
10 10 3 1 6 7 11 0 -2 3 4 8
Однако, как вы можете заметить во фрейме данных, иногда частица не обнаружена при i = 1 или позже. Это означает, что я получаю значение NA. Следовательно, включая еще один l oop с IF, чтобы, если эта 1-я точка времени была NA, R переместилась бы go к следующей временной точке, пока не найдет значение не NA для вычитания. Поэтому я придумал это, используя ifelse вместо IF, поскольку последнее может иметь дело только с одним значением, в то время как мой ввод фактически является столбцом:
for (i in 1:5){ # iterate for each time point i
for (j in 1:5){ # if first time point has no value (NA) scan the row for next time point until an object is detected
ifelse(!is.na(df[,2+j-1]),
df$Disp <- (df[,2+i-1]-df[,2+j-1]), # create a new column with the calculated displacement for i time point
next) # if time point is NA go to next j (next fixed initial time point to test)
}
nam.Disp <- paste("Disp", i, sep = "") #rename new column Disp+time point number
names(df)[names(df) == 'Disp'] <- nam.Disp
}
df
particule.ID x.position1 x.position2 x.position3 x.position4 x.position5 Disp1 Disp2 Disp3 Disp4 Disp5
1 1 5 6 6 7 9 -4 -3 -3 -2 0
2 2 NA NA 2 4 5 NA NA -3 -1 0
3 3 4 8 7 9 NA NA NA NA NA NA
4 4 7 7 7 7 7 0 0 0 0 0
5 5 1 2 4 5 6 -5 -4 -2 -1 0
6 6 NA 1 3 5 NA NA NA NA NA NA
7 7 2 2 1 0 2 0 0 -1 -2 0
8 8 NA NA NA 0 3 NA NA NA -3 0
9 9 NA NA NA 5 8 NA NA NA -3 0
10 10 3 1 6 7 11 -8 -10 -5 -4 0
Каким-то образом это возвращает неправильные значения. Похоже, что вычисления произошли в обратном направлении: Disp1 = x5-x1, Disp2 = x5-x2, Disp3 = x5-x3 et c ... в то время как я ожидал: Disp1 = x1-x1, Disp2 = x2-x1, Disp3 = x3-x1 et c. Как это могло вызвать включение нового для l oop и функции ifelse? Что я делаю неправильно? Возможно, есть способ сделать это вручную, но, поскольку на самом деле у меня есть как минимум 60 временных моментов, если не больше, задача будет сложной.
Кроме того, если вы считаете, что есть гораздо более умный способ сделать это Пожалуйста, поделитесь! И если я забуду включить важные детали, которые помогут вам лучше понять, просто дайте мне знать.
Большое спасибо!
Flo