避免在 R 中的大型数据集上使用循环,同时在重复数据上添加第二个循环
Avoiding using loops on large dataset in R while adding a second onto repeat data
我正在努力重新格式化大量水质数据,以便反馈到数据库中。志愿者在取数据时,往往会用一份水样进行多次测试,并记录为相同的样本编号、日期和时间。但是,数据库不会接受这个并且需要不同的采样时间。从历史上看,解决这个问题的方法是为相同样本号的每个后续测量增加一秒钟。例如,
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 是重复样本编号和时间的标题。这确实有效,但有点慢。我希望找到一种更好的方法,尤其是不依赖嵌套循环的方法。
考虑将 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
我正在努力重新格式化大量水质数据,以便反馈到数据库中。志愿者在取数据时,往往会用一份水样进行多次测试,并记录为相同的样本编号、日期和时间。但是,数据库不会接受这个并且需要不同的采样时间。从历史上看,解决这个问题的方法是为相同样本号的每个后续测量增加一秒钟。例如,
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 是重复样本编号和时间的标题。这确实有效,但有点慢。我希望找到一种更好的方法,尤其是不依赖嵌套循环的方法。
考虑将 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