2012-12-22 118 views
1

我想清理这个代码,并想知道如果任何人有任何建议如何在没有循环R运行此。我有一个名为数据的数据集,有100个变量和200,000个观测值。我想要做的事实质是扩展数据集,方法是将每个观察值乘以特定的标量,然后将这些数据组合在一起。最后,我需要一个包含800,000个观察值(我有四个类别创建)和101个变量的数据集。这是我写的这样做的一个循环,但效率非常低,我希望更快,更高效。如何矢量化在R循环

datanew <- c() 
for (i in 1:51){ 
    for (k in 1:6){ 
    for (m in 1:4){ 

     sub <- subset(data,data$var1==i & data$var2==k) 

     sub[,4:(ncol(sub)-1)] <- filingstat0711[i,k,m]*sub[,4:(ncol(sub)-1)] 

     sub$newvar <- m 

     datanew <- rbind(datanew,sub) 

    } 
    } 
} 

请让我知道你的想法和感谢您的帮助。

下面是2K的意见,而不是200K

# SAMPLE DATA 
#------------------------------------------------# 
    mydf <- as.data.frame(matrix(rnorm(100 * 20e2), ncol=20e2, nrow=100)) 
    var1 <- c(sapply(seq(41), function(x) sample(1:51)))[1:20e2] 
    var2 <- c(sapply(seq(2 + 20e2/6), function(x) sample(1:6)))[1:20e2] 
    #----------------------------------# 
    mydf <- cbind(var1, var2, round(mydf[3:100]*2.5, 2)) 
    filingstat0711 <- array(round(rnorm(51*6*4)*1.5 + abs(rnorm(2)*10)), dim=c(51,6,4)) 
#------------------------------------------------# 
+8

请帮助我们来帮助你,通过(1)张贴一些样本数据,以及(2)解释你希望在这里用言语完成的事情。另外请注意,您不需要引用您在“subset”中进行子集的data.frame。 –

回答

1

你可以尝试以下一些样本数据。请注意,我们用呼叫mapply替换了前两个for循环,第三个用for循环调用了lapply。 另外,我们正在创建两个矢量,我们将结合使用矢量化乘法。

# create a table of the i-k index combinations using `expand.grid` 
ixk <- expand.grid(i=1:51, k=1:6) 

    # Take a look at what expand.grid does 
    head(ixk, 60) 


# create two vectors for multiplying against our dataframe subset 
multpVec <- c(rep(c(0, 1), times=c(4, ncol(mydf)-4-1)), 0) 
invVec <- !multpVec 

    # example of how we will use the vectors 
    (multpVec * filingstat0711[1, 2, 1] + invVec) 


# Instead of for loops, we can use mapply. 
newdf <- 
    mapply(function(i, k) 

    # The function that you are `mapply`ing is: 
    # rbingd'ing a list of dataframes, which were subsetted by matching var1 & var2 
    # and then multiplying by a value in filingstat 
    do.call(rbind, 
     # iterating over m 
     lapply(1:4, function(m) 

      # the cbind is for adding the newvar=m, at the end of the subtable 
      cbind(

      # we transpose twice: first the subset to multiply our vector. 
      # Then the result, to get back our orignal form 
      t(t(subset(mydf, var1==i & mydf$var2==k)) * 
       (multpVec * filingstat0711[i,k,m] + invVec)), 

      # this is an argument to cbind 
      "newvar"=m) 
    )), 

    # the two lists you are passing as arguments are the columns of the expanded grid 
    ixk$i, ixk$k, SIMPLIFY=FALSE 
) 

# flatten the data frame 
newdf <- do.call(rbind, newdf) 



两点要注意:

(1)尽量不使用的话像datatabledfsub等,通常使用的功能 在我所用mydf上述代码data的地方。

(2)您可以使用apply(ixk, 1, fu..),而不是说我用了mapply,但我认为mapply在这种情况下

好运使得更清洁的代码,并欢迎SO