在for循环中子集唯一值

时间:2019-07-05 16:29:54

标签: r for-loop

我正在尝试计算鲨鱼在特定深度停留的时间比例。

我的数据集是这样的:

    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持续到2018年6月26日。每天有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))
}

但是,我遇到了一些错误。首先,运行for循环时得到Error: unexpected '}' in "}"。我不确定

中的每一天是否正确
for(i in 1:length(uniq.day)){
  day =  subset(df1, date == [[i]])
}

我希望它在m中输出18/3/2018和19/3/2018的函数结果,但是我不确定在哪里出错。

1 个答案:

答案 0 :(得分:3)

不是使用循环并执行多个子设置选项,而是有更好的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函数通过day和deployID进行子集设置,然后计算<70和> 30的病例数,并除以每个子集中的病例总数。

这也比使用循环快得多。