加快这个循环?

时间:2014-05-12 01:33:18

标签: r loops indexing

我有一个名为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

在循环中,没有任何东西看起来计算量太大。还有更好的选择吗?

3 个答案:

答案 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)。