为R中的循环进行速度调谐
我读过矢量化作为加速for循环的解决方案。但是,我在for循环中创建的数据结构似乎需要是data.frame/table 以下是场景: 我有一个大的序列号和时间戳表。多个时间戳可应用于同一序列号。我只想要每个序列号的最新时间戳 我现在的方法是创建一个具有唯一序列号的向量。然后,对于通过该向量的每个循环,我创建一个临时表,其中保存序列号/时间戳组合“temp”的所有观察值。然后,我使用tail命令获取这个临时表的最后一个条目,并将其放入另一个表中,该表最终将保存所有唯一的序列号及其最新的时间戳“last.pass”。最后,我只需从起始表serial number/timestamp组合中删除“last.pass”中找不到的行 这是我的密码:为R中的循环进行速度调谐,r,performance,for-loop,automation,vectorization,R,Performance,For Loop,Automation,Vectorization,我读过矢量化作为加速for循环的解决方案。但是,我在for循环中创建的数据结构似乎需要是data.frame/table 以下是场景: 我有一个大的序列号和时间戳表。多个时间戳可应用于同一序列号。我只想要每个序列号的最新时间戳 我现在的方法是创建一个具有唯一序列号的向量。然后,对于通过该向量的每个循环,我创建一个临时表,其中保存序列号/时间戳组合“temp”的所有观察值。然后,我使用tail命令获取这个临时表的最后一个条目,并将其放入另一个表中,该表最终将保存所有唯一的序列号及其最新的时间戳“l
#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]
我的最终问题是,如何在加速脚本的同时保持脚本的自动化特性,比如说,通过矢量化或将其转化为函数
谢谢你 这个怎么样。在不清楚输入数据是什么样子的情况下,我猜测了一下
# 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)))
对于每个HDDSN,此数据有多个结束日期
merge.data <- data.frame(HDDSN = 1001:1100, ENDDATE = sample(9999, 1000))
df[!duplicated(df[["HDDSN"]], fromLast=TRUE),]
然后查找每个HDDSN的最后一个条目
merge.data <- data.frame(HDDSN = 1001:1100, ENDDATE = sample(9999, 1000))
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而不是向量上查找重复的关键点!重复的DDF[,ckey1,键2],如下所示:
> 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会将列粘贴到一个字符串中,舍入错误可能会慢慢出现。您应该包括样本输入数据和该样本数据的所需输出,以便从您的描述中找出问题。这听起来很简单,可以使用dplyr或数据表,甚至是基函数。但是,正如Flick先生所说,我们需要一个例子。只需5-10行输入和所需的输出。使用dput共享您的数据,我们将获得所有的写入类。此外,当您说“大”时,最好有一个刻度。你是说超过1000万行?100-1000万?“一个数量级的估计就足够了。”马丁·摩根说得对。这就是数据的样子。大小接近一百万行。我正在尝试他的方法,稍后会回复您。Martin,您如何调整最后一个命令以适应df中的两个变量。也就是说,它适用于复合键场景。@PabloBoswell我试图用我对您问题的理解更新回答。谢谢!你知道这个独特的功能是否也能起到类似的作用吗。你能不能只写last.pass[uniquelast.pass[,cHDDSN,PHEADNO],fromLast=TRUE,]