Поднабор уникальных значений внутри цикла for - PullRequest
1 голос
/ 05 июля 2019

Я пытаюсь рассчитать долю времени, которое акула проводит на определенных глубинах.

Мой набор данных выглядит так:

    deployID depth         datetime       date
   1        A  66.5 18/03/2018 00:00 18/03/2018
   2        A  55.0 18/03/2018 00:02 18/03/2018
   3        A  28.5 18/03/2018 00:05 18/03/2018
   4        A  23.5 18/03/2018 00:07 19/03/2018
   5        A  48.5 18/03/2018 00:10 19/03/2018
   6        A  53.5 18/03/2018 00:12 19/03/2018

, но df1$date работает до 26/6/2018. Каждый день проводится 576 наблюдений, каждые 2,5 минуты.

Я написал простую функцию для вычисления пропорции на определенную дату:

pct.day <- function(a.depth) {
  part.day <- length(a.depth$datetime) / length(sharkA$datetime)
  return(part.day)
}

и цикл for, который, как я надеялся, вычислит это для каждого дня, указанного в df1.

uniq.day = unique(df1$date)
prop_day = list()
for(i in 1:length(uniq.day)){
  day =  subset(df1, date == [[i]])
  sharkA = subset(day, deployID=="A")
  a = subset(sharkA, depth<70 & depth >30)
  prop_day[[i]] <- with(day, pct.day(a))
  m <- data.frame(unlist(prop_day))
}

Однако я сталкиваюсь с некоторыми ошибками. Во-первых, я получаю Error: unexpected '}' in "}" при запуске цикла for. Я не уверен, что правильно подбираю каждый отдельный день в

for(i in 1:length(uniq.day)){
  day =  subset(df1, date == [[i]])
}

Я хотел бы, чтобы он вывел результат функции за 18.03.2017 и 19.03.2017 в m, но я не уверен, где я ошибаюсь.

1 Ответ

3 голосов
/ 05 июля 2019

Вместо использования цикла и выполнения нескольких вариантов поднабора есть лучшие параметры R, такие как функция split вдоль lapply.

Еще один более быстрый вариант - использование пакета dplyr. Этот пакет очень удобен для решения подобных проблем. Вот возможное однострочное решение:

df<-structure(list(deployID = structure(c(1L, 1L, 1L, 1L, 1L, 1L), .Label = "A", class = "factor"), 
    depth = c(66.5, 55, 28.5, 23.5, 48.5, 53.5), datetime = c("18/03/2018 00:00", 
    "18/03/2018 00:02", "18/03/2018 00:05", "18/03/2018 00:07", 
    "18/03/2018 00:10", "18/03/2018 00:12"), date = structure(c(1L, 
    1L, 1L, 2L, 2L, 2L), .Label = c("18/03/2018", "19/03/2018"
    ), class = "factor")), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6"))

library(dplyr)
df %>% group_by(deployID, date) %>% summarize(targetdepth=sum(depth<70 & depth>30 ), total=n(), targetdepth/total)

 #deployID date       targetdepth total `targetdepth/total`
 #<fct>    <fct>            <int> <int>               <dbl>
 #A        18/03/2018           2     3               0.667
 #A        19/03/2018           2     3               0.667

Здесь функция group_by выполняет поднабор по дням и deployID, затем вычисляет количество случаев <70 и> 30 и делит их на общее количество случаев в каждом подмножестве.

Это также значительно быстрее, чем при использовании цикла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...