2012-12-22 166 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