2017-05-26 250 views
0

我有一個有1020行和800列的數據幀(cenMca)。如何求和R中的數據框中特定數量的列?

每4列,我有一組數據,我稱之爲「cen」。所以,從第1列到第4列,我有cen 1,從5到8,我有cen2等等。

我想將cenMca劃分成尺寸等於1020行×4列的200個更小的數據框,並對每行的值進行求和。爲此,我將apply作爲每行的函數總和,但是,我搜索了以我想要的方式拆分數據幀的方法,但未能這樣做。另外,我不知道如何遍歷這些較小的數據框來保存每個不同的名稱。

所以我認爲,不是將cenMca分成更小的數據框,而是將cenMca中的值相加,並將它們分配給我稱爲sumvec的單個數據框。因此,cenMca中的每4列,我會有一個相應的列sumvec。這給出總和維數等於1020行和200列。

爲了實現這一點,我想:

sumvec = matrix(NA,1020,200) 

    for (i in 1:1020){ 
    for (j in seq(1,800,4)){ 
     sumvec[i,(j+3)/4] = cenMca[i,j]+cenMca[i,j+1]+cenMca[i,j+2]+cenMca[i,j+3] 
    } 

    } 

通過行第一for運行,並且該第二for貫穿列。第二個for我的增量是4,因爲那樣我就可以在一個循環中獲得我想要的所有四個值。

我知道這遠沒有效率,但我認爲它會奏效。 當我運行腳本後,我得到了這個:enter image description here

我試過warnings()但沒有出現。我所有的總結是「不適用」

我該如何解決這個問題? 有關如何完成這項工作的其他技術將不勝感激。謝謝。

+1

請出示小重複的例子, – akrun

回答

1

這似乎是一個很好的申請rowSums。您可以使用lapply在您嘗試執行的分組列上運行它。

我將使用類似的數據設置爲@ R.Schifini:

set.seed(1) 
z <- matrix(rnorm(1020*800), ncol = 800) 

使它成爲一個數據幀,像您的數據。

z <- as.data.frame(z) 

現在將數據幀分組爲4列組,每組運行rowSums

x <- lapply(seq.int(1, ncol(z), 4), 
     function(i) { 
      rowSums(z[ , i:(i+3) ]) 
     }) 

將它作爲單個數據框與您需要的列名綁定在一起。

x <- as.data.frame(x, col.names = paste0("cen", seq_along(x))) 

這是輸出的一個小例子。

> head(x[1:6]) 
     cen1  cen2  cen3  cen4  cen5  cen6 
1 -0.8027240 -0.7437158 -1.5305678 -0.7055544 2.0122082 0.7851487 
2 0.0854064 0.2422316 -2.5071390 1.7854231 -3.5219698 -0.7699433 
3 1.2738387 1.7360087 1.4317099 -3.3501584 -1.8412381 -2.1396324 
4 -0.5864149 -0.5648199 -0.3099392 -1.9144969 0.7874474 -2.4840934 
5 -0.3887289 -1.0745042 -1.9729363 1.8971846 -4.3374676 2.5744197 
6 0.9104741 -0.7546090 4.2516971 1.0335885 2.6814576 -0.2548666 
+0

嘿,Rosscova。感謝您的意見。儘管我試圖運行你的代碼,並且每次點擊lapply塊時,都會出現這個錯誤:「rowSums(cenMca [,x:(x + 3)])中的錯誤:'x'必須是數字。用typeof我看到「x」是字符。我試圖用1020 * 200矩陣替換x,但它不起作用。 –

+0

這一步在'lapply'調用中,例如'x'是迭代器。換句話說,'x'就是'seq.int(1,ncol(z),4)'的所有值,一個接一個地被使用,但是隻爲'lapply'創建和使用(你不能真正檢查它是'lapply'調用之外的類,因爲直到'lapply'運行才真正存在)。如果你在其他地方使用'x',你可以選擇一個不同的迭代器,例如'... function(i){rowSums(z [,i:(i + 3)])} ...'。 – rosscova

+0

再次感謝您的反饋。我做了必要的調整,並且按照它應該的那樣工作。 –

1

這是你想要實現的嗎?

我將創建一個樣品基質(也工作,如果它是一個數據幀)

z = matrix(floor(runif(120, 0, 100)), ncol = 12) 
> z 
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] 
[1,] 37 50 37 0 71 84 29 65 0 34 33 65 
[2,] 53 60 17 44 39 94 16 66 72 12 27 32 
[3,] 10 26 5 26 11 58 39 47 71 38 11 19 
[4,] 80 42 65 93 24 50 45 96 18 92  4 11 
[5,] 73 36 57 71 86 18 43 40 64 80 37 99 
[6,] 5 94 98 16 43 0 51 84 54 75 33 37 
[7,] 48 12 60 47 49 87 84 75 33 95 17 56 
[8,] 92 7 6 69 69 13 5 53 63 99 62 73 
[9,] 4 96 16 46 76 2 55 87 82 60 39 87 
[10,] 29 44 47 95 15 93 68 46 70  2 95 57 

然後在組中添加的四列:

result = z[,seq(1,12,by = 4)]+z[,seq(2,12,by = 4)]+z[,seq(3,12,by = 4)]+z[,seq(4,12,by = 4)] 

> result 
     [,1] [,2] [,3] 
[1,] 124 249 132 
[2,] 174 215 143 
[3,] 67 155 139 
[4,] 280 215 125 
[5,] 237 187 280 
[6,] 213 178 199 
[7,] 167 295 201 
[8,] 174 140 297 
[9,] 162 220 268 
[10,] 215 222 224 
1

首先,你不」 t需要遍歷行。 R適用於矢量。

其次,sumvec中的NAs可能是cenMca中的NAs的結果。如果您在cenMca中有NA,請使用sum而不是+

for (j in seq(1,800,4)) sumvec[,(j+3)/4] <- apply(cenMca[,j:(j+3)],1,sum, na.rm=T) 

希望,這有助於。

+0

你可能會發現'rowSums'遠遠超過你的'申請(...... 1,總和...)'調用效率。 – rosscova

+0

你說得對。我只是堅持認爲'rowSums'也適用於數據框架:)感謝提醒我。 –

相關問題