我已经阅读了矢量化作为加速for循环的解决方案。但是,我在for循环中创建的数据结构似乎需要是data.frame / table。
以下是该方案:
我有一个大型的序列号和时间戳表。多个时间戳可以应用于相同的序列号。我只想要每个序列号的最新时间戳。
我现在的方法是创建一个具有唯一序列号的向量。然后,对于通过此向量的每个循环,我创建一个临时表,其中包含序列号/时间戳组合的所有观察结果(' temp')。然后我接受这个临时表的最后一个条目(使用tail命令)并将其放入另一个表中,该表最终将保存所有唯一的序列号及其最新的时间戳(' last.pass')。最后,我只是从起始表序列中删除无法找到数字/时间戳组合的行' last.pass'
这是我的代码:
#create list of unique serial numbers found in merged 9000 table
hddsn.unique <- unique(merge.data$HDDSN)
#create empty data.table to populate
last.pass < data.table(HDDSN=as.character(1:length(hddsn.unique)),
ENDDATE=as.character(1:length(hddsn.unique)))
#populate last.pass with the combination of serial numbers and their latest timestamps
for (i in 1:length(hddsn.unique)) {
#create temporary table that finds all serial number/timestamp combinations
temp <- merge.data[merge.data$HDDSN %in% hddsn.unique[i],][,.(HDDSN, ENDDATE)]
#populate last.pass with the latest timestamp record for every serial number
last.pass[i,] <- tail(temp, n=1)
}
match <- which(merge.data[,(merge.data$HDDSN %in% last.pass$HDDSN) &
(merge.data$ENDDATE %in% last.pass$ENDDATE)]==TRUE)
final <- merge.data[match]
我的最终问题是,如何通过矢量化或将其转换为函数来加快速度,从而保持此脚本的自动化特性。
谢谢!!!
答案 0 :(得分:0)
这个怎么样?如果不清楚输入数据是什么样的,我就会猜测。
# make some dummy data with multiple visits per serial
merge.data <- data.frame(HDDSN = 1001:1020,
timestamps = sample(1:9999, 100))
# create a function to find the final visit for a given serial
fun <- function(serial) {
this.serial <- subset(merge.data, HDDSN==serial)
this.serial[which.max(this.serial$timestamps), ]
}
# apply the function to each serial number and clean up the result
final <- as.data.frame(t(sapply(unique(merge.data$HDDSN), fun)))
答案 1 :(得分:0)
此数据对每个HDDSN都有几个ENDDATE
merge.data <- data.frame(HDDSN = 1001:1100, ENDDATE = sample(9999, 1000))
按顺序排列,首先是HDDSN,然后是ENDDATE
df = merge.data[do.call("order", merge.data),]
然后找到每个HDDSN的最后一个条目
df[!duplicated(df[["HDDSN"]], fromLast=TRUE),]
以下说明了关键步骤
> head(df, 12)
HDDSN ENDDATE
701 1001 4
101 1001 101
1 1001 1225
301 1001 2800
201 1001 6051
501 1001 6714
801 1001 6956
601 1001 7894
401 1001 8234
901 1001 8676
802 1002 247
402 1002 274
> head(df[!duplicated(df[["HDDSN"]], fromLast=TRUE),])
HDDSN ENDDATE
901 1001 8676
902 1002 6329
803 1003 9947
204 1004 8825
505 1005 8472
606 1006 9743
如果有复合键,则在data.frame而不是向量!duplicated(df[, c("key1", "key2")])
上查找重复项,如下所示:
> df = data.frame(k0=c(1:3, 1:6), k1=1:3)
> df[!duplicated(df, fromLast=TRUE),]
k0 k1
1 1 1
2 2 2
3 3 3
7 4 1
8 5 2
9 6 3
(行号来自原始数据帧,因此第4-6行是重复的)。 (可能需要注意,特别是如果其中一列是数字的,因为duplicated.data.frame将列粘贴到一个字符串中并且舍入错误可能会蔓延)。