我可以通过循环来解决这个问题吗?

时间:2020-05-28 12:36:42

标签: r loops dataframe

我有一个大型的生态数据集,其中包含需要修复的部署ID。

相机陷阱已部署了十年,并且相机陷阱的位置被记录为部署ID。但是,相机陷阱可能已在不同时间两次部署在同一位置。在这种情况下,部署ID被记录为相同,但是它们必须是唯一的。

请澄清一下:一次只能将一个摄像头陷阱部署到一个位置。但是在过去的十年中,有些位置有多个摄像头陷阱。

所以我的目标是使它们成为唯一的部署ID。

尝试:我知道相机陷阱的部署时间未超过3个月。因此,使用DateTime,如果超过100天,则可以假定它是重新部署,并且我想为其分配唯一的部署ID。所以我用DateDiff创建了一个列

for (i in 2:nrow(data)){
    if (data$deploymentID[i] == data$deploymentID[i-1]){
        data$DateDiff[i] <- as.Date(data$DateTime[i], format = '%Y%m%d') - as.Date(data$DateTime[i-1], format = '%Y%m%d')
    }
}

然后,我认为如果我先按部署ID排序,然后再按DateTime排序数据...

data[order(data$deploymentID, data$DateTime), ]

我将能够使用遍历数据帧的循环,如果DateDiff> 100,则以下所有与部署ID相同的行都将创建唯一的DeploymentID。

但是,我正在努力为最后一部分创建一个工作循环!

I've attached a picture to show the structure of my data

非常感谢

1 个答案:

答案 0 :(得分:1)

这是dplyr的解决方案。首先按ID分组并安排日期。然后,您可以使用lag函数来计算日期差。然后,您用cumsum计算出部署相差100天以上的频率,并使用它生成唯一的ID:

data <- data.frame(ID = c(rep("B1-2-41", 8), rep("B1-2-44", 8)),
                   date = c(rep(as.Date("2019-05-01"), 8),
                            rep(as.Date("2018-01-01"), 6),
                            as.Date("2018-05-01"), as.Date("2018-10-01")))
library(dplyr)

data_new <- data %>% 
  group_by(ID) %>% 
  arrange(date) %>% 
  mutate(date_diff = date - lag(date, default = first(date)),
         unique_ID = paste0(ID, "_", cumsum(date_diff > 100) + 1)) %>% 
  ungroup() %>% 
  arrange(ID)

> data_new
# A tibble: 16 x 4
   ID      date       date_diff unique_ID
   <fct>   <date>     <drtn>    <chr>    
 1 B1-2-41 2019-05-01   0 days  B1-2-41_1
 2 B1-2-41 2019-05-01   0 days  B1-2-41_1
 3 B1-2-41 2019-05-01   0 days  B1-2-41_1
 4 B1-2-41 2019-05-01   0 days  B1-2-41_1
 5 B1-2-41 2019-05-01   0 days  B1-2-41_1
 6 B1-2-41 2019-05-01   0 days  B1-2-41_1
 7 B1-2-41 2019-05-01   0 days  B1-2-41_1
 8 B1-2-41 2019-05-01   0 days  B1-2-41_1
 9 B1-2-44 2018-01-01   0 days  B1-2-44_1
10 B1-2-44 2018-01-01   0 days  B1-2-44_1
11 B1-2-44 2018-01-01   0 days  B1-2-44_1
12 B1-2-44 2018-01-01   0 days  B1-2-44_1
13 B1-2-44 2018-01-01   0 days  B1-2-44_1
14 B1-2-44 2018-01-01   0 days  B1-2-44_1
15 B1-2-44 2018-05-01 120 days  B1-2-44_2
16 B1-2-44 2018-10-01 153 days  B1-2-44_3