19 jul 2014

Matrices y tablas en Matlab


3.1. Notas introductorias 

En esta parte se tratan matrices, algunas tablas y se ilustra cómo usar bucles para completar matrices. Aunque existe abundante literatura en la red. Las formas básicas de crear columna y matrices en Matlab es:

%Vector fila
>> A=[1 2 3]

A =

     1     2     3

%Vector columna
>> B=[1; 2; 3]

B =

     1
     2
     3

%Es equivalente
>> B = [1 2 3]'
>> B = [1:3]'

Estos dos últimos comando son equivalentes, en el primero transpone un vector fila en columna ( ' ), en el segundo se ilustra como usar operaciones vectorizadas en Matlab, lo que evita el uso de bucle cuyo uso para construir matrices se presenta en el apartado 3.6.

%Matriz bidimensional
C=[1 2; 2 4; 3 6]

C =

     1     2
     2     4
     3     6

Esta matriz bidimensional, seria un problema si se tratara de una matriz de mayor dimensión, sin embargo Matlab permite obtenerla de forma vectoriada. la matriz C, se puede obtener usando:

>> C = [1:3; 2:2:6]'

C =

     1     2
     2     4
     3     6

La primera parte del comando anterior ordena una secuencia de números que vaya desde el 1 hasta el 3, y una segunda columna que llama, también de forma vectorizada, a crear una columna, que vaya del 2 al 6, en pasos de 2 en 2. Un comando que realiza una operación similar a esta última citada es linspace, este permite dividir intervalos según fuese requerido. Por ejemplo, dividir en 5 un intervalo que va desde 0 hasta 10.  Es decir obtener un vector con x valores igualmente espaciados.

>> D = linspace(0,10,5)

D =

         0    2.5000    5.0000    7.5000   10.0000

Nótese que el uso de los dos puntos (:) tiene un uso extendido en Matlab. Se puede acceder a la primera columna de una matriz especificando (:,1), accedería a la columna 1.

>> C(:,1)

ans =

     1
     2
     3

Si se usa C(:,2:end) recorrerá todas las filas, desde la segunda hasta la última columna. El siguiente comando permite representar conjuntamente, datos de números aleatorios que se generaron de forma independientes. Matlab también permite representar conjuntamente datos que han sido generado de forma independiente. El siguiente comando permite representar conjuntamente, datos de números aleatorios que se generaron de forma independientes. (el ; se coloca para poder colocar varias instrucciones en una misma linea) 

>> y = [rand(1,10)]';, x=[rand(1,10)]';, z=[y,x]

z =

    0.7513    0.8407
    0.2551    0.2543
    0.5060    0.8143
    0.6991    0.2435
    0.8909    0.9293
    0.9593    0.3500
    0.5472    0.1966
    0.1386    0.2511
    0.1493    0.6160
    0.2575    0.4733 

En resumen y dado a la abundante literatura respecto al tema que existe en la red, en la próxima tabla se resume un conjunto de comandos básicos de operaciones con matrices:

Construir matrices

Forma de una matriz
matriz(fila, columna)
dimensiones de la matriz
[nfilasM, ncolsM]=size(A)
    Crear una matriz
A = [16 3 2; 1 11 8; 6 7 1; 4 1 1]
    matriz a ceros
A = zeros (3, 5)
    matriz a unos
A = ones (3, 5)
    matriz identidad
eye(3)  
    Matrices x distantes
linspace(xmin, xmax, n)
x=xmin:stepsize:xmax


Llamar o editar un elemento
A(1,4)
  Última fila
sum(A(:,end))
  Borrar la segunda columna
X(:,2) = []


builds a table
x = (1:0.1:2)’;
logs = [x log10(x)]


Matrices esperciales

   Transpuesta
A’
   matriz a ceros
A = zeros (3, 5)
   matriz a unos
A = ones (3, 5)
   matriz identidad
eye(3)  
   dimensiones de la matriz
[nfilasM, ncolsM]=size(A)
   Tomar la diagonal
diag(A)
   The determinant
d = det(A)
   Inversa
X = inv(A)
   Triangulares
tril(A) triu(A)
   Autovectores y Autovalores
[V, D] = eig(A)
   Cholesky
chol(A)
   Valores singulares
svd(A)


Operaciones con matices

Sumar

   Sumar filas
sum(A’)’
   Sumar la diagonal
sum(diag(A))
   Crear matriz simétrica
A + A’
multiplicación

   Multiplicar
A’*A
Exponencial matricial
expm(A)


Estadísticos

Estadísticos por columna
mu = mean(D);
sigma = std(D)
Nota. En cuanto a los estadísticos de matices, en la parte de Estadística descriptiva se explicó su uso para trabajar por fila o columna.

Trabajar con matrices abre muchas posibilidades, por ejemplo podemos generar una matriz con los números pares entre 1 y 10 y sus respectivos logaritmos. Este ultimo comando es especialmente útil para cuando se desea calcular factoriales dobles de forma vectorizada con Matlab.

>> num_pares = (2:2:10)'
>> Log=[num_pares log(num_pares)]

Log =

    2.0000    0.6931
    4.0000    1.3863
    6.0000    1.7918
    8.0000    2.0794
   10.0000    2.3026

3.2. Poner texto y números en un cuadro

Esta tarea no es trivial en Matlab. No es posible insertar textos en las matrices de Matlab, si se llaman directamente. Se deben usar comillas simples y llamar mediante llaves (no corchetes).

>> nom={'nerys', 'salami', 'platano'}
>> class(nom)

Este último comando permite utilizar   “cell”, comando que permite guardar diversos tipos de datos. Cuyos objetos y dimensiones se acceden mediante {}. En el siguiente ejemplo se muestra como especificar una tabla con los nombres y la media de un conjunto de datos.

% Ejemplo: Clasificacioens promedio por notas obtenidas
%Especificas clases y datos
nota  = [58 67 80 96]
notas = {'Rep','Extra','Apro','Sobre'}

%Completando tablas
  cellnotas=cell(4,2);
     cellnotas (:,1)=notas; % los : indica es una operación vectorizada

       %se pueden además completar celdas directamente
       Rep   = nota<70; Extra = nota<70 & nota>60;  
       Apro  = nota>70; Sobre = nota>85;

    cellnotas(1,2)= {mean(Rep)};,   cellnotas(2,2)= {mean(Extra)};
    cellnotas(3,2)= {mean(Apro)};,  cellnotas(4,2)= {mean(Sobre)};
cellnotas

cellnotas =

    'Rep'      [0.5000]
    'Extra'    [0.2500]
    'Apro'     [0.5000]
    'Sobre'    [0.2500]

3.3. Clasificaciones

En ocasiones es necesario crear tablas donde se incluyan además el nombre de la clase con que se esté trabajando. Por ejemplo se pueden hacer tablas de frecuencia, incluyendo clasificaciones específicas.

%Tabla de frecuencia con etiquetas de clases
>> nota  = [75 85 92 15 65 82 72 45 94 85 86 70 68 56 57 63 72 14]
>> notao = ordinal(nota,{'Rep','Extra','Apro','Sobre'},{},[0,59,69.9,85,100])

>> tabulate(notao)

  Value    Count   Percent
    Rep        5     27.78%
  Extra        3     16.67%
   Apro        5     27.78%
  Sobre        5     27.78%

3.4. Tablas y matrices con operadores lógicos

El uso de operadores lógicos se supone conocido. Utilizar operadores lógicos para obtener información de las tablas y vectores calculados en Matlab, se presenta a continuación. 

%Calcular la media de estudiantes susmendidos
nota  = [75 85 92 15 65 82 72 45 94 85 86 70 68 56 57 63 72 14]
      suspenso = nota<70         %indica 1/0. 1 si suspendieron               
     nota_susp =nota(suspenso)  %muestra la nota de los que suspendi…
      mean(nota_susp)            %media de notas de los que suspedieron

El promedio de estudiante suspendidos, se puede obtener, aprovechando que la matriz [suspenso] es dicotómica o binaria, llamando el promedio de dicha matriz o calculando directamente la media, el próximo cuadro presenta respectivamente, dichos comandos.

>> mean(suspenso)
>> sum(suspenso)/length(nota)

Existen en Matlab un conjunto de operadores lógicos que permiten aplicar pruebas lógicas a matrices de datos. 

Comandos
Descripción
any(nota>85)
%arroja un 1 si en la matriz nota hay por lo menos un número mayor a 85 (cumpla alguna condición)
any(C(:,1)>=3)
%Aplica la misma condición sobre una fila
all(nota>85)
%revisa si todos los elementos cumplen una condición
find(nota>85)
Busca valores y posiciones que cumplan determinadas condiciones

Ejemplo: usar la función find para sustituir los elementos de una matriz que cumplen determinadas condiciones.

N=magic(4)

N =

    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1

%buscar valores mayores a 10
>>    J = find(N>=10)
>> N(J) = 10*ones(size(J))

N =

    10     2     3    10
     5    10    10     8
     9     7     6    10
     4    10    10     1

         3.5. Tablas de contingencia y etiquetas filas y columnas

Teniendo dos vectores de datos, X referido al sexo 1==hombre 0==mujer y una segunda variable fuma que muestra un 1 en el caso que la persona fume. El comando usado agrega el chi2 y el pvalor, usando la hipótesis nula de independencia entre variables.

>> sexo = round(rand(1,10))'
>> fuma = round(rand(1,10))'  
>> [table,chi2,p] = crosstab(sexo, fuma)

table =

     2     4
     2     2


chi2 =

    0.2778


p =

    0.5982

Hasta ahora hemos obtenido todas las tablas y matrices sin las debidas etiquetas, que permitan identificar su contenido. La tabla de contingencia anterior se podría modificar de forma que aparezcan las debidas etiquetas.

%ahora modificamos el comando para obtener las debidas etiquetas
table = array2table(table,              ...
      'VariableNames',{'Hombre','Mujer'},...
      'RowNames',{'Fumador','No_fuma'});

disp('Tabla cruzada')
 disp(table)

Tabla cruzada
                 Hombre       Mujer         
                --------    ---------   
    Fumador            2            4    
    No_fuma            2            2   

3.6. Usar bucles para completar matrices de datos

Una forma adicional de construir matrices se encuentra en los bucles. Por ejemplo, la Matriz B, obtenida en el primer apartado, se podría obtener alternativamente usando:

>>  for I = 1:3,
      n(i) = i;
     end

>>  n =

     1     2     3

Esta forma de construer matrices se vuelve especialmente útil cuando necesitamos completar matrices bidimensionales, siguiendo el criterio de completar ya sea por fila o por columna. 

>> %Recorrer una matriz por fila
for i=1: nfilasA                 % para cada fila
     for j=1: ncolsA
              sentencias
       end
 end

% recorrer la matriz por columnas
for j=1: ncolsA                  % para cada columna
      for i=1: nfilasA
              sentencias
        end
end

en el primer caso se tiene:

 Si aun no se ve se puede aclarar viéndolo arbitraria donde cada numero muestra en que paso el programa trabajo en esa celda. en los próximo se muestra como el programa va trabajando según el criterio que se va indicando. En el primero ejecuta la sentencia en la primera fila y trabaja todos sus elementos columna por columna y en la segunda trabaja todos los elementos de la columna fila por fila.

>> %Recorrer una matriz por fila
n =

     1     2
     3     4
     5     6

recorrer la matriz por columnas
n =

     1     4
     2     5
     3     6

Para ver una aplicación un poco mas avanzada de estos comando, en el siguiente comando se utiliza el bucle anidado for para simular un proceso autoregresivo (AR(1)) de primer orden, rellenando una matriz por fila. La clave esta en el orden en que se colocan los for, pues estos indican la forma en como deberá ir trabajando el programa.

M = 2; T = 12; X0 = 10; phi0 = 0.0; phi1 = 0.95; sigma = 0.25;
X= zeros(M,T);

%Se completa la matriz anterior con un bucle que completa, por fila, el
%numero de trayectorias especificadas en la función.
   for i=1:M                             
       for j=2:T                             
           u(i,j)=sigma*rand();
          X(i,1)=phi0+phi1*X0+rand()*sigma;
          X(i,j)= phi0+phi1*X(i,j-1)+u(i,j);
       end
   end
  

REFERENCIAS BIBLIOGRÁFICAS

Lopez, Beatriz (2009). Estadística. Disponible en: http://eio.usc.es/pub/pateiro/files/iq0809pateiro.pdf

Creando variables por grupos en dplyr (group_by + mutate)

  Simulemos una base de hogares, donde se identifica el hogar, el sexo (1 mujer) y provincia y edad para cada miembro.   # Definir la lista ...