У меня есть фрейм данных, который выглядит следующим образом:
# Set RNG
set.seed(33550336)
# Create toy data frame
df <- expand.grid(day = 1:10, dist = seq(0, 100, by = 10))
df1 <- df %>% mutate(region = "Here")
df2 <- df %>% mutate(region = "There")
df3 <- df %>% mutate(region = "Everywhere")
df_ref <- do.call(rbind, list(df1, df2, df3))
df_ref$value <- runif(nrow(df_ref))
# > head(df_ref)
# day dist region value
# 1 1 0 Here 0.39413117
# 2 2 0 Here 0.44224203
# 3 3 0 Here 0.44207487
# 4 4 0 Here 0.08007335
# 5 5 0 Here 0.02836093
# 6 6 0 Here 0.94475814
Это представляет эталонный фрейм данных, и я хотел бы сравнить наблюдения с ним. Мои наблюдения взяты в определенный день, который находится в этом фрейме справочных данных (т. Е. day
- это целое число от 1 до 10) в регионе, который также находится в этом фрейме данных (т. Е. Here
, There
или Everywhere
), но расстояние (dist
) равно , а не , обязательно является целым числом от 0 до 100. Например, мой кадр данных наблюдений (df_obs
) может выглядеть следующим образом:
# Observations
df_obs <- data.frame(day = sample(1:10, 3, replace = TRUE),
region = sample(c("Here", "There", "Everywhere")),
dist = runif(3, 0, 100))
# day region dist
# 1 6 Everywhere 68.77991
# 2 7 There 57.78280
# 3 10 Here 85.71628
Поскольку dist
не является целым числом, я не могу просто найти значение, соответствующее моим наблюдениям, в df_ref
, например так:
df_ref %>% filter(day == 6, region == "Everywhere", dist == 68.77991)
Итак, я создал функцию поиска, которая использует функцию линейной интерполяции approx
:
lookup <- function(re, di, da){
# Filter to day and region
df_tmp <- df_ref %>% filter(region == re, day == da)
# Approximate answer from distance
approx(unlist(df_tmp$dist), unlist(df_tmp$value), xout = di)$y
}
Применение этого к моему первому наблюдению дает,
lookup("Everywhere", 68.77991, 6)
#[1] 0.8037013
Тем не менее, когда я применяю функцию с помощью mutate
, я получаю другой ответ.
df_obs %>% mutate(ref = lookup(region, dist, day))
# day region dist ref
# 1 6 Everywhere 68.77991 0.1881132
# 2 7 There 57.78280 0.1755198
# 3 10 Here 85.71628 0.1730285
Я подозреваю, что это потому, что lookup
неправильно векторизовано. Почему я получаю разные ответы и как мне исправить мою функцию lookup
, чтобы избежать этого?