2016-02-20 38 views
1

假設我有一個矩陣,5乘以5的水果名稱(5類水果)。我想在這個現有矩陣中添加5個新列,並在每行中添加單個水果的總數,最後再添加一行以顯示每種同類水果的總和。數據矩陣是這樣的,如何在數據矩陣中添加與新列相同的字符串的總數與R

[,1] [,2] [,3] [,4] [,5] 
[1,]mango  banana   mango 
[2,]apple kiwi   banana 
[3,]   mango 
[4,]mango  apple 
[5,]     orange 

我想輸出(數據幀)這樣,

[,1] [,2] [,3] [,4] [,5] [apple] [banana] [kiwi] [mango] [orange] 
[1,]mango  banana  mango 0  1  0  2  0 
[2,]apple kiwi  banana   1  1  1  0  0 
[3,]   mango    0  0  0  1  0 
[4,]mango  apple    1  0  0  1  0 
[5,]     orange   0  0  0  0  1 
[6,]        2  2  1  4  1 

我已經試過grep,它是整個矩陣分解成列向量。我實際上並不知道如何用R完成整個數據矩陣。這裏是代碼,

fruits <- matrix(c("mango", "", "banana", "", "mango", "apple", "kiwi", "", "banana", "","", "", "mango", "", "", "mango", "", "apple", "", "", "", "", "", "orange", ""), nrow = 5, ncol = 5, byrow = TRUE) 
fruits$apple <- length(grep("apple", fruits[1:nrow(fruits), 1:ncol(fruits)])) 
fruits$banana <- length(grep("banana", fruits[1:nrow(fruits), 1:ncol(fruits)])) 
fruits$kiwi <- length(grep("kiwi", fruits[1:nrow(fruits), 1:ncol(fruits)])) 
fruits$mango <- length(grep("mango", fruits[1:nrow(fruits), 1:ncol(fruits)])) 
fruits$orange <- length(grep("orange", fruits[1:nrow(fruits), 1:ncol(fruits)])) 

請幫忙。

+1

您不能在矩陣中混合不同的數據類型。也許你應該使用數據框。 – Stibu

+0

感謝您的糾正 –

回答

2

我們也可以融化並與數投下的數據幀。然後添加一行總和:

library(reshape2) 
library(tidyr) 

#melt fruits matrix 
g <- gather(as.data.frame(t(fruits))) 

#cast data wide and bind to original matrix 
d <- cbind(fruits, dcast(g, key~value)[-(1:2)]) 

#add row of sums 
rbind(d,c(rep("", 5),colSums(d[-(1:5)]))) 
#  1 2  3  4  5 apple banana kiwi mango orange 
# 1 mango  banana  mango  0  1 0  2  0 
# 2 apple kiwi  banana   1  1 1  0  0 
# 3    mango     0  0 0  1  0 
# 4 mango  apple     1  0 0  1  0 
# 5     orange   0  0 0  0  1 
# 6         2  2 1  4  1 
+0

謝謝@Pierre Lafortune對你的精彩幫助。 –

+0

隨時。樂於幫助 –

2

無法使用矩陣創建您指定的輸出,因爲矩陣包含單個類型的值。計數將因此轉換爲字符,這是一種解決方案,但可能不是您想要的。我建議你使用數據框來存儲你的結果。

我在四個步驟中提出以下解決方案。

  1. 創建矩陣中所有水果名稱的矢量。我使用額外的步驟從該矢量中刪除空字符串。

    all_fruits <- unique(as.vector(fruits)) 
    all_fruits <- all_fruits[nchar(all_fruits) > 0] 
    
  2. 創建包含在all_fruits每每個水果的行計數列表。

    fruit_count <- lapply(all_fruits, function(fruit) 
            rowSums(matrix(grepl(fruit, fruits), nrow = nrow(fruits)))) 
    names(fruit_count) <- all_fruits 
    

    這部分有點棘手,所以我補充幾句話。您需要使用grepl才能返回邏輯向量。不幸的是,fruits的維度參數丟失了,並且返回一個簡單的向量,必須將其轉換回矩陣。 rowSums然後用於總結的搜索項(即,水果的名字)已被每行中發現的次數。這是有效的,因爲當這樣做時,TRUE被轉換爲1並且FALSE被轉換爲0。

  3. fruits轉換爲數據框並添加具有空字符的附加行。將fruit_count轉換爲數據框並添加列總和。

    fruits_df <- rbind(as.data.frame(fruits), "") 
    fruit_count_df <- as.data.frame(fruit_count) 
    fruit_count_df[nrow(fruits) + 1, ] <- colSums(fruit_count_df) 
    
  4. 將兩個數據幀一起。

    out <- data.frame(fruits_df, fruit_count_df) 
    out 
    ##  X1 X2  X3  X4 X5 mango apple kiwi banana orange 
    ## 1 mango  banana  mango  2  0 0  1  0 
    ## 2 apple kiwi  banana   0  1 1  1  0 
    ## 3    mango     1  0 0  0  0 
    ## 4 mango  apple     1  1 0  0  0 
    ## 5     orange   0  0 0  0  1 
    ## 6         4  2 1  2  0 
    
+2

尼斯解決方案。如果你願意的話,這是一種縮短它的方法。 'all_fruits < - 獨一無二(掃描(what =「character」,text = fruits))'用一行而不是兩行。 –

+0

@PierreLafortune感謝您的提示;我不會想到這種可能性。 – Stibu