我有一个名为cpue的数据集,有330万行。我已经创建了一个名为dat.frame的数据集的子集。 (请参阅下面的cpue和dat.frame的头部。)我在dat.frame中添加了两个新字段:“ssh_vec”和“ssh_mag”。虽然cpue和dat.frame的头部看起来相同,但其余的行实际上并没有相同的顺序。
head(cpue)
code event Lat Long stat_area Day Month Year id
1 BCO 447602 -43.45 182.73 49 17 3 1995 1
head(dat.frame)
code event Lat Long stat_area Day Month Year id cal.jdate ssh_vec ssh_mag
1 BCO 447602 -43.45 182.73 49 17 3 1995 1 2449857 56.83898 4.499350
目前,我正在运行一个循环,使用唯一标识符“id”将ssh_vec和ssh_mag变量添加到“cpue”:
cpue$ssh<- NA
cpue$sshmag<- NA
for(i in 1:nrow(dat.frame))
{
ndx<- dat.frame$id[i]
cpue_full$ssh[ndx]<- dat.frame$ssh_vec[i]
cpue_full$sshmag[ndx]<- dat.frame$ssh_mag[i]
}
这已经在周末运行,只能达到:
i
[1] 132778
......出自:
nrow(dat.frame)
[1] 2797789
在循环中,没有任何东西看起来计算量太大。还有更好的选择吗?
答案 0 :(得分:2)
您确定需要for
循环吗?我认为这可能是等同的:
cpue_full$ssh[dat.frame$id]<- dat.frame$ssh_vec
cpue_full$sshmag[dat.frame$id]<- dat.frame$ssh_mag
答案 1 :(得分:1)
我建议您查看data.table
。由于我没有您的数据,这里有一个使用虚拟数据的简单示例。
library(data.table)
N = 10^6
dat <- data.table(
x = rnorm(1000),
g = sample(LETTERS, N, replace = TRUE)
)
dat2 <- dat[,list(mx = mean(x)),g]
h = merge(dat, dat2, 'g')
答案 2 :(得分:1)
你甚至需要循环吗?从发布的代码片段看起来不会。
cpue_full$ssh[dat.frame$id] <- dat.frame$ssh_vec
cpue_full$sshmag[dat.frame$id]<- dat.frame$ssh_mag
应该有效。一个快速(和小)的虚拟示例:
set.seed(666)
ssh <- rnorm(10^4)
datf <- data.frame(id = sample.int(10000L), ssh = NA)
system.time(datf$ssh[datf$id] <- ssh) # user 0, system 0, elapsed 0
# Reset dummy data
datf$ssh <- NA
system.time({
for (i in 1:nrow(datf) ) {
ndx <- datf$id[i]
datf$ssh[ndx] <- ssh[i]
}
} ) # user 2.26, system 0.02, elapsed 2.28
PS - 我没有使用过data.table包,所以我没有按照Ramnath的回答。一般来说,如果可能的话,你应该避免循环(参见The Rune的财富(142)和圆圈3)。