Применение итеративной / неагрегирующей функции для нескольких подмножеств данных в R - PullRequest
0 голосов
/ 07 июля 2019

Я пытаюсь запустить функцию, которая требует индексации в подмножествах набора данных, и у меня возникают проблемы с настройкой функции.В частности, я пытаюсь вычислить расстояние по определенному трансекту в данном году, поэтому для каждого подмножества мне нужно 1) определить конечную точку в трансекте и 2) вычислить евклидово расстояние вдоль линии от этой конечной точки на всехдругие места в подмножестве.

Эта функция, кажется, работает, если я рассматриваю весь набор данных как один разрез:

df <- data.frame(
  Transect = c(rep(1,4),rep(2,4)),
  YYYY = c(2015,2015,2016,2016,2015,2015,2016,2016),
  X = seq(2,16, by = 2),
  Y = c(1,2,3,5,6,13,22,31))

df$dist <- NA

f <- function(X, Y) {
  xs_start <- match(min(X), X)  #assumes no transects are perfectly N-S
  for (n in 1:length(X)){
    dist[n] <- (((Y[n]-Y[xs_start])^2)+((X[n]-X[xs_start])^2))^.5
  }
  return(dist)
}
attach(df)
f(X, Y)
detach(df)

Однако выполнение его на подмножестве данных доставляет мне проблемы.Я могу успешно установить подкадр данных, используя data.table и dplyr, но я сталкиваюсь с различными проблемами при попытке запустить функции на подмножествах.Большая часть документации, которую я нашел, была сосредоточена на способах агрегирования подмножеств данных (а иногда и последующего присоединения итогового номера ко всей группе).

Используя data.table, я могу получить первый трансект для правильного вычисления, но остальные дают NA, и весь результирующий вектор затем присоединяется к каждой группе, а не только к результатам из этого подмножества.

library(data.table)
dt <- data.table(df)
dt[,f(X, Y), by = .(Transect, YYYY)]

Использование dplyr также вариант, но, опять же, я не уверен, как заставить его работать для функций, которые не агрегируют данные.

library(dplyr)
df  %>%
  group_by(Transect, YYYY) %>%
  mutate(dist = f(X, Y))

Приведенный выше код приводит к Error: Column 'dist' must be length 2 (the group size) or one, not 8.

Есть мысли?Заранее спасибо!

1 Ответ

2 голосов
/ 07 июля 2019

Чтобы добавить столбец dist, который вычисляет евклидовы расстояния от местоположения конечной точки (наименьшая координата X) до всех других местоположений в каждой группе года трансект, вы можете сделать:

## data
df <- data.frame(
    Transect = c(rep(1,4),rep(2,4)),
    YYYY = c(2015,2015,2016,2016,2015,2015,2016,2016),
    X = seq(2,16, by = 2),
    Y = c(1,2,3,5,6,13,22,31))

## with dplyr
library(dplyr)

df %>%
    group_by(Transect, YYYY) %>%
    mutate(dist = sqrt((Y - Y[which.min(X)])^2 + (X - min(X))^2)) %>%
    ungroup()
#> # A tibble: 8 x 5
#>   Transect  YYYY     X     Y  dist
#>      <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1        1  2015     2     1  0   
#> 2        1  2015     4     2  2.24
#> 3        1  2016     6     3  0   
#> 4        1  2016     8     5  2.83
#> 5        2  2015    10     6  0   
#> 6        2  2015    12    13  7.28
#> 7        2  2016    14    22  0   
#> 8        2  2016    16    31  9.22

## with data.table
library(data.table)

setDT(df)[, dist := sqrt((Y - Y[which.min(X)])^2 + (X - min(X))^2), by = c("Transect", "YYYY")][]
#>    Transect YYYY  X  Y     dist
#> 1:        1 2015  2  1 0.000000
#> 2:        1 2015  4  2 2.236068
#> 3:        1 2016  6  3 0.000000
#> 4:        1 2016  8  5 2.828427
#> 5:        2 2015 10  6 0.000000
#> 6:        2 2015 12 13 7.280110
#> 7:        2 2016 14 22 0.000000
#> 8:        2 2016 16 31 9.219544
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...