Я хочу добавить новый столбец T
в df1
, который зависит от отношения между df1$x
и df2
. Чтобы вы это хорошо понимали, df1$x
- это глубина рыбы, а разные столбцы df2$T
- это температура воды на разных глубинах (5, 15, 25 и 35 метров). Я хочу оценить в df1$T
температуру воды, в которой рыба находилась в зависимости от температуры воды в колонне. Как пример:
df1<- data.frame(DateTime=c("2016-08-01 08:01:17","2016-08-01 09:17:14","2016-08-01 10:29:31","2016-08-01 11:35:02","2016-08-01 12:22:45","2016-08-01 13:19:27","2016-08-01 14:58:17","2016-08-01 15:30:10"), x = c(NA,27,44,33,15,17,22,35))
df1$DateTime<- as.POSIXct(df1$DateTime, format = "%Y-%m-%d %H:%M:%S", tz= "UTC")
df1$DateTime1<- strptime(df1$DateTime, "%Y-%m-%d %H",tz= "UTC") # I create a DateTime variable in the same format than in `df2`.
df1$DateTime1<- as.POSIXct(df1$DateTime1, format = "%Y-%m-%d %H", tz= "UTC") # I transform it to POSIXct.
df2<- data.frame(DateTime=c("2016-08-01 08:00:00","2016-08-01 09:00:00","2016-08-01 10:00:00","2016-08-01 11:00:00","2016-08-01 12:00:00","2016-08-01 13:00:00","2016-08-01 14:00:00","2016-08-01 15:00:00"),T5=c(27.0,27.5,27.1,27.0,26.8,26.3,26.0,26.3),T15=c(23.0,23.4,23.1,22.7,22.5,21.5,22.0,22.3),T25=c(19.0,20.0,19.5,19.6,16.0,16.3,16.2,16.7),T35=c(16.0,16.0,16.5,16.7,16.3,16.7,16.9,16.7))
df2$DateTime<- as.POSIXct(df2$DateTime, format = "%Y-%m-%d %H:%M:%S", tz= "UTC")
df1
DateTime x DateTime1
1 2016-08-01 08:01:17 NA 2016-08-01 08:00:00
2 2016-08-01 09:17:14 27 2016-08-01 09:00:00
3 2016-08-01 10:29:31 44 2016-08-01 10:00:00
4 2016-08-01 11:35:02 33 2016-08-01 11:00:00
5 2016-08-01 12:22:45 15 2016-08-01 12:00:00
6 2016-08-01 13:19:27 17 2016-08-01 13:00:00
7 2016-08-01 14:58:17 22 2016-08-01 14:00:00
8 2016-08-01 15:30:10 35 2016-08-01 15:00:00
df2
DateTime T5 T15 T25 T35
1 2016-08-01 08:00:00 27.0 23.0 19.0 16.0 # No difference bigger than 5 at any interval (neither T5 and T15, nor T15 and T25 nor T25 and T35).
2 2016-08-01 09:00:00 27.5 23.4 20.0 16.0 # No difference bigger than 5 at any interval (neither T5 and T15, nor T15 and T25 nor T25 and T35).
3 2016-08-01 10:00:00 27.1 23.1 19.5 16.5 # No difference bigger than 5 at any interval (neither T5 and T15, nor T15 and T25 nor T25 and T35).
4 2016-08-01 11:00:00 27.0 22.7 19.6 16.7 # No difference bigger than 5 at any interval (neither T5 and T15, nor T15 and T25 nor T25 and T35).
5 2016-08-01 12:00:00 26.8 22.5 16.0 16.3 # A difference greater than 5 between `df2$T15` and `df2$25`.
6 2016-08-01 13:00:00 26.3 21.5 16.3 16.7 # A difference greater than 5 between `df2$T15` and `df2$25`.
7 2016-08-01 14:00:00 26.0 22.0 16.2 16.9 # A difference greater than 5 between `df2$T15` and `df2$25`.
8 2016-08-01 15:00:00 26.3 22.3 16.7 16.7 # A difference greater than 5 between `df2$T15` and `df2$25`.
Я хочу следующее:
Когда df1$x
(глубина моей рыбы) ниже, чем df$T5
, я хочу, чтобы df1$x
было df2$T5
. Когда df1$x
(глубина моей рыбы) больше, чем df$T35
, я хочу, чтобы df1$x
был df2$T35
. Если глубина моей рыбы df1$x
составляет от 5 до 35, посмотрите, в каком интервале (T5 и T15, T15 и T25, T25 и T35) и:
Если разница между концами интервала меньше 5, то df1$x
является интерполяцией между значениями в концах интервала.
Если разница между концами интервала больше 5, разделите интервал пополам. В верхней половине (например, между df$T5
и df$T10
) интерполируйте df1$x
, предполагая df2$10
== df2$T15
. В нижней половине (от df2$T10
до df2$T15
) df1$x
== df2$T15
.
Результат, который я ожидаю, будет:
result
DateTime x DateTime1 T
1 2016-08-01 08:01:17 NA 2016-08-01 08:00:00 NA
2 2016-08-01 09:17:14 27 2016-08-01 09:00:00 19.20
3 2016-08-01 10:29:31 44 2016-08-01 10:00:00 16.50
4 2016-08-01 11:35:02 33 2016-08-01 11:00:00 17.28
5 2016-08-01 12:22:45 15 2016-08-01 12:00:00 22.50
6 2016-08-01 13:19:27 17 2016-08-01 13:00:00 19.42
7 2016-08-01 14:58:17 22 2016-08-01 14:00:00 16.20
8 2016-08-01 15:30:10 35 2016-08-01 15:00:00 16.70
Я подумал об этом как о решении, но я хотел бы знать, есть ли более простой код, так как этот, я думаю, займет довольно много времени.
y <- seq(from=5, to=15, by=1) # I create a vector with 11 levels. The upper level corresponds to the above water temperature sensor `df2$T5` and the last level to the below sensor `df2$T15´.
y[2:10]<- "NA" # We don't know water temperature at the levels between the upper and last one. We either interpolate them or assume that they are equal to the water temperature at the lower level.
y<- as.numeric(y)
y
x <- seq(from=15, to=25, by=1) # The same criteria. In this case, the vector is for x when `df1$x` is between 15 and 25.
x[2:10]<- "NA"
x<- as.numeric(x)
x
k <- seq(from=25, to=35, by=1) # The same criteria. In this case, the vector is for x when `df1$x` is between 25 and 35.
k[2:10]<- "NA"
k<- as.numeric(k)
k
for (i in 1:nrow(df1)) {
if (is.na(df1$x[i])){
df1$T[i] <-"NA"
}else if (!is.na(df1$x[i]) & df1$x[i] > 0 & df1$x[i] <= 5){
df1$T[i] <- df2$T5[which(df1$DateTime1[i] == df2$DateTime)]
}else if (!is.na(df1$x[i]) & df1$x[i] > 5 & df1$x[i] <= 15 & df2$T15[which(df1$DateTime1[i] == df2$DateTime)] - df2$T5[which(df1$DateTime1[i] == df2$DateTime)] < 5){
y[1]<- df2$T5[which(df1$DateTime1[i] == df2$DateTime)]
y[11]<- df2$T15[which(df1$DateTime1[i] == df2$DateTime)]
y <-na.approx(y)
df1$T[i] <- y[round(df1$x[i])-4]
y <- seq(from=5, to=15, by=1)
y[2:10]<- "NA"
y<- as.numeric(y)
}else if (!is.na(df1$x[i]) & df1$x[i] > 15 & df1$x[i] <= 25 & df2$T25[which(df1$DateTime1[i] == df2$DateTime)] - df2$T15[which(df1$DateTime1[i] == df2$DateTime)] < 5){
x[1]<- df2$T15[which(df1$DateTime1[i] == df2$DateTime)]
x[11]<- df2$T25[which(df1$DateTime1[i] == df2$DateTime)]
x <-na.approx(x)
df1$T[i] <- x[round(df1$x[i])-14]
x <- seq(from=15, to=25, by=1)
x[2:10]<- "NA"
x<- as.numeric(x)
}else if (!is.na(df1$x[i]) & df1$x[i] > 25 & df1$x[i] <= 35 & df2$T35[which(df1$DateTime1[i] == df2$DateTime)] - df2$T25[which(df1$DateTime1[i] == df2$DateTime)] < 5){
k[1]<- df2$T25[which(df1$DateTime1[i] == df2$DateTime)]
k[11]<- df2$T35[which(df1$DateTime1[i] == df2$DateTime)]
k <-na.approx(k)
df1$T[i] <- k[round(df1$x[i])-24]
k <- seq(from=25, to=35, by=1)
k[2:10]<- "NA"
k<- as.numeric(k)
}else if (!is.na(df1$x[i]) & df1$x[i] > 5 & df1$x[i] <= 15 & df2$T15[which(df1$DateTime1[i] == df2$DateTime)] - df2$T5[which(df1$DateTime1[i] == df2$DateTime)] > 5){
y[1]<- df2$T5[which(df1$DateTime1[i] == df2$DateTime)]
y[6]<- df2$T15[which(df1$DateTime1[i] == df2$DateTime)]
y[11]<- df2$T15[which(df1$DateTime1[i] == df2$DateTime)]
y <-na.approx(y)
df1$T[i] <- y[round(df1$x[i])-4]
y <- seq(from=5, to=15, by=1)
y[2:10]<- "NA"
y<- as.numeric(y)
}else if (!is.na(df1$x[i]) & df1$x[i] > 15 & df1$x[i] <= 25 & df2$T25[which(df1$DateTime1[i] == df2$DateTime)] - df2$T15[which(df1$DateTime1[i] == df2$DateTime)] > 5){
x[1]<- df2$T15[which(df1$DateTime1[i] == df2$DateTime)]
x[6]<- df2$T25[which(df1$DateTime1[i] == df2$DateTime)]
x[11]<- df2$T25[which(df1$DateTime1[i] == df2$DateTime)]
x <-na.approx(x)
df1$T[i] <- x[round(df1$x[i])-14]
x <- seq(from=15, to=25, by=1)
x[2:10]<- "NA"
x<- as.numeric(x)
}else if (!is.na(df1$x[i]) & df1$x[i] > 25 & df1$x[i] <= 35 & df2$T35[which(df1$DateTime1[i] == df2$DateTime)] - df2$T25[which(df1$DateTime1[i] == df2$DateTime)] > 5){
k[1]<- df2$T25[which(df1$DateTime1[i] == df2$DateTime)]
k[6]<- df2$T35[which(df1$DateTime1[i] == df2$DateTime)]
k[11]<- df2$T35[which(df1$DateTime1[i] == df2$DateTime)]
k <-na.approx(k)
df1$T[i] <- k[round(df1$x[i])-24]
k <- seq(from=25, to=35, by=1)
k[2:10]<- "NA"
k<- as.numeric(k)
}else if (!is.na(df1$x[i]) & df1$x[i] > 35){
df1$T[i] <- df2$T35[which(df1$DateTime1[i] == df2$DateTime)]
}
}