2016-02-20 3 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 <- unique (scan (what =" character ", text = fruits))' с одной строкой вместо двух. –

+0

@PierreLafortune Спасибо за подсказку; Я бы не подумал об этой возможности. – Stibu