首页 > 解决方案 > 避免在 R 中的大型数据集上使用循环,同时在重复数据上添加一秒

问题描述

我正在重新格式化大量水质数据,以便反馈到数据库中。志愿者在取数据时,往往会使用一个水样进行多次测试,并记录为相同的样本编号、日期和时间。但是,数据库不会接受这一点,需要采样时间不同。解决这个问题的方法在历史上一直是在相同样本编号的每个后续测量中添加一秒。例如,

Sample Number                DateTime
 180433               2019-11-04 12:30:00
 180433               2019-11-04 12:30:00
 180433               2019-11-04 12:30:00
 180433               2019-11-04 12:30:00
 180433               2019-11-04 12:30:00

那么我需要时间为 12:30:00、12:30:01、12:30:02、12:30:03、12:30:04。虽然我为此编写了一些代码,但它有点笨拙,我知道必须有一个更优雅的方法。

LIMS_dup<-LIMS_data[duplicated(LIMS_data[,c(4,8:9)]),c(4,8:9)]

x<-NA
for (i in 1:length(unique(LIMS_dup$CustomerSampleNumber))){
  x<-which(as.integer(LIMS_data$CustomerSampleNumber)==as.integer(unique(LIMS_dup$CustomerSampleNumber)[i]))
  if (length(x)>1){
    for (j in 2:length(x)){
      LIMS_data$CollectTime[x[j]]<-LIMS_data$CollectTime[x[j-1]]+1
    }
  }
}

LIMS_data 是我的主要标题,LIMS_dup 是重复样本数量和时间的标题。这确实有效,但它有点慢。我希望找到一种更好的方法,尤其是不依赖嵌套循环的方法。

标签: rloopsvectorization

解决方案


考虑ave将按组的顺序计数(这里是样本数)添加到POSIXct日期时间类型(即添加秒数):

df$New_DateTime <- with(df, DateTime + (ave(as.numeric(DateTime), Sample_Number, FUN=seq_along)-1))

df
#   Sample_Number            DateTime        New_DateTime
# 1        180433 2019-11-04 12:30:00 2019-11-04 12:30:00
# 2        180433 2019-11-04 12:30:00 2019-11-04 12:30:01
# 3        180433 2019-11-04 12:30:00 2019-11-04 12:30:02
# 4        180433 2019-11-04 12:30:00 2019-11-04 12:30:03
# 5        180433 2019-11-04 12:30:00 2019-11-04 12:30:04

Online Demo


推荐阅读