Soluciones de la Práctica de la Unidad 5

Vectores

Ejercicio 1

#' Suma de los elementos de un vector
#'
#' Calcula la suma de todos los elementos de un vector numérico.
#'
#' @param v Un vector numérico.
#' @return La suma de los elementos del vector.
#' @examples
#' suma(c(1, 2, 3))  # Devuelve 6
suma <- function(v) {
  resultado <- 0
  for (i in 1:length(v)) {
    resultado <- resultado + v[i]
  }
  return(resultado)
}

Ejercicio 2

#' Suma componente a componente de dos vectores
#'
#' Suma dos vectores numéricos de igual longitud, elemento a elemento.
#' Si las longitudes no coinciden, se detiene con error.
#'
#' @param u Un vector numérico.
#' @param v Un vector numérico.
#'
#' @return Un vector numérico con la suma componente a componente.
#'
#' @examples
#' sumar_vectores(c(1, 2, 3), c(4, 5, 6))  # Devuelve c(5, 7, 9)
sumar_vectores <- function(u, v) {
  nu <- length(u)
  nv <- length(v)
  if (nu != nv) {
    stop("Las dimensiones de los vectores no coinciden.")
  }
  suma <- numeric(nu)
  for (i in 1:nu) { 
    suma[i] <- u[i] + v[i]
  }
  return(suma)
}

Ejercicio 3

#' Ordenar un vector numérico de forma ascendente
#'
#' Ordena los elementos de un vector numérico en orden ascendente usando un 
#' algoritmo de comparación simple.
#'
#' @param v Un vector numérico.
#'
#' @return Un vector numérico con los elementos ordenados de menor a mayor.
#'
#' @examples
#' ordenar_asc(c(3, 1, 4, 2))  # Devuelve c(1, 2, 3, 4)
ordenar_asc <- function(v) {
  n <- length(v)
  for (i in 1:n) {
    for (j in i:n) {
      if (v[i] > v[j]) {
        tmp <- v[i]
        v[i] <- v[j]
        v[j] <- tmp 
      }
    }
  }
  return(v)
}

Ejercicio 4

#' Máximo de un vector numérico
#'
#' Encuentra el valor máximo en un vector numérico y su posición.
#'
#' @param v Un vector numérico.
#'
#' @return Un vector numérico de longitud 2. El primer elemento es el valor 
#' máximo, y el segundo, la posición donde se encuentra (primera aparición).
#'
#' @examples
#' maximo(c(4, 2, 7, 1))  # Devuelve c(7, 3)
#' maximo(c(10))          # Devuelve c(10, 1)
maximo <- function(v) {
  n <- length(v)
  mayor <- v[1]
  posicion <- 1
  for (i in 1:n) {
    # Desde i = 1 para que también funcione si n = 1
    if (v[i] > mayor) {
      mayor <- v[i]
      posicion <- i
    }
  }
  resultado <- c("mayor" = mayor, "posicion" = posicion)
  return(resultado)
}

Ejercicio 5

  1. Producto escalar de dos vectores.

    #' Producto escalar de dos vectores
    #'
    #' Calcula el producto escalar entre dos vectores numéricos de igual 
    #' longitud.
    #'
    #' @param u Un vector numérico.
    #' @param v Un vector numérico.
    #'
    #' @return Un número que representa el producto escalar entre u y v.
    #' @details Se detiene con error si las longitudes no coinciden.
    #'
    #' @examples
    #' prod_escalar(c(1, 2, 3), c(4, 5, 6))  # Devuelve 32
    #' prod_escalar(c(1, 2), c(1, 2, 3))     # Error
    prod_escalar <- function(u, v) {
      nu <- length(u)
      nv <- length(v)
      if (nu != nv) {
        stop("Las dimensiones de los vectores no coinciden.")
      }
      suma <- 0
      for (i in 1:nu) {
        suma <- suma + u[i] * v[i]
      }
      return(suma)
    }
  2. Producto vectorial de dos vectores de dimensión 3

    #' Producto vectorial de dos vectores de dimensión 3
    #'
    #' Calcula el producto vectorial entre dos vectores numéricos de dimensión 
    #' 3.
    #'
    #' @param u Un vector numérico de longitud 3.
    #' @param v Un vector numérico de longitud 3.
    #'
    #' @return Un vector numérico de longitud 3 que representa el producto 
    #' vectorial u × v
    #' 
    #' @details Se detiene con error si alguno de los vectores no tiene 
    #' dimensión 3.
    #'
    #' @examples
    #' prod_vectorial(c(1, 0, 0), c(0, 1, 0))  # Devuelve c(0, 0, 1)
    #' prod_vectorial(c(1, 2), c(3, 4))        # Error
    prod_vectorial <- function(u, v) {
      nu <- length(u)
      nv <- length(v)
      if (nu != 3 || nv != 3) {
        stop("Los vectores no son de dimensión 3.")
      }
      resultado <- c(u[2] * v[3] - u[3] * v[2], 
                     u[3] * v[1] - u[1] * v[3], 
                     u[1] * v[2] - u[2] * v[1])
      return(resultado)
    }
  3. Producto mixto de tres vectores de dimensión 3

    #' Producto mixto de tres vectores de dimensión 3
    #'
    #' Calcula el producto mixto de tres vectores u, v y w  de dimensión 3,
    #' definido como el producto escalar de w con el producto vectorial de u y v
    #'
    #' @param u Un vector numérico de longitud 3.
    #' @param v Un vector numérico de longitud 3.
    #' @param w Un vector numérico de longitud 3.
    #'
    #' @return Un número que representa el producto mixto.
    #' @details Se detiene con error si alguno de los vectores no tiene 
    #' dimensión 3.
    #'
    #' @examples
    #' prod_mixto(c(1, 0, 0), c(0, 1, 0), c(0, 0, 1)) # Devuelve 1
    #' prod_mixto(c(1, 2), c(3, 4, 5), c(6, 7, 8))    # Error
    prod_mixto <- function(u, v, w) {
      resultado1 <- prod_vectorial(u, v)
      resultado2 <- prod_escalar(resultado1, w)
      return(resultado2)
    }
  4. Mostrar productos vectoriales y escalares entre tres vectores

    #' Mostrar productos vectoriales y escalares entre tres vectores
    #'
    #' Calcula y muestra por consola el producto escalar entre v y w, 
    #' el producto vectorial entre u y w, y el producto mixto entre v, w y u.
    #'
    #' @param u Un vector numérico de longitud 3.
    #' @param v Un vector numérico de longitud 3.
    #' @param w Un vector numérico de longitud 3.
    #'
    #' @return No devuelve un valor, solo imprime los resultados por consola.
    #'
    #' @examples
    #' mostrar_productos(c(5, 8, 2), c(2, 3, -1), c(1, 2, 3))
    mostrar_productos <- function(u, v, w) {
      prod_esc <- prod_escalar(v, w)
      prod_mix <- prod_mixto(v, w, u)
      cat("El producto escalar entre v y w es:", prod_esc, "\n")
      cat("El producto mixto entre v, w y u es:", prod_mix, "\n")
      resultado <- c("prod_escalar" = prod_esc, "prod_mixto" = prod_mix)
      return(resultado)
    }

Ejercicio 6

#' Mostrar números primos hasta n usando distintos enfoques de la Criba de 
#' Eratóstenes
#'
#' Esta función muestra los números primos hasta n utilizando distintos enfoques
#' de la criba de Eratóstenes.
#' El argumento enfoque permite elegir entre varias implementaciones:
#' "asumir_primos", "tachar", o "encerrado".
#'
#' @param n Un número entero positivo que indica el límite superior para 
#' la búsqueda de primos.
#' @param enfoque Un string que indica el enfoque a usar: "asumir_primos",
#' "tachar" o "encerrado".
#'
#' @details
#' Los enfoques disponibles son:
#' 
#' - "asumir_primos"
#' Parte de un vector lógico donde todos los números son considerados primos 
#' inicialmente (excepto el 1). Luego, se descartan los múltiplos de cada 
#' número que aún es considerado primo.
#'
#' - "tachar"
#' Utiliza un vector "tachado" para marcar con TRUE los números que no son 
#' primos (es decir, los tachados). Comienza tachando el 1, y luego los 
#' múltiplos de cada número no tachado. Los primos son los que quedan sin
#' tachar al final.
#'
#' - "encerrado"
#' Usa un vector lógico llamado "encerrado" donde todos los números empiezan 
#' como TRUE. Cada vez que se encuentra un primo, se marcan (ponen en FALSE) 
#' todos sus múltiplos, indicando que ya no están "encerrados".
#' 
#' @return Ninguno. La función imprime en consola los números primos encontrados.
#'
#' @examples
#' mostrar_primos(30, enfoque = "asumir_primos")
#' mostrar_primos(30, enfoque = "tachar")
#' mostrar_primos(30, enfoque = "encerrado")
mostrar_primos <- function(n, enfoque = c("asumir_primos", "tachar", "encerrado")) {
  if (enfoque == "asumir_primos") {
    es_primo <- rep(TRUE, n)
    es_primo[1] <- FALSE
    for (i in 2:n) {
      if (es_primo[i]) {
        print(i)
        j <- 2 * i
        while (j <= n) {
          es_primo[j] <- FALSE
          j <- j + i
        }
      }
    }
  } else if (enfoque == "tachar") {
    tachado <- logical(n)
    tachado[1] <- TRUE
    for (i in 2:n) {
      if (!tachado[i]) {
        print(i)
        j <- 2 * i
        while (j <= n) {
          tachado[j] <- TRUE
          j <- j + i
        }
      }
    }
  } else if (enfoque == "encerrado") {
    encerrado <- rep(TRUE, n)
    for (i in 2:n) {
      if (encerrado[i]) {
        print(i)
        for (j in seq(i, n, i)) {
          encerrado[j] <- FALSE
        }
      }
    }
  }
}

Matrices

Ejercicio 7

#' Suma de dos matrices
#'
#' Esta función toma dos matrices del mismo tamaño y devuelve una nueva matriz 
#' que representa la suma elemento a elemento de ambas. Si las dimensiones 
#' no coinciden, imprime un mensaje de error y devuelve NULL
#'
#' @param A Una matriz numérica.
#' @param B Una matriz numérica del mismo tamaño que A.
#'
#' @return Una matriz con la suma de A y B
#' @details Produce error si las dimensiones no coinciden.
#'
#' @examples
#' A <- matrix(1:4, nrow = 2)
#' B <- matrix(5:8, nrow = 2)
#' sumar_matrices(A, B)
sumar_matrices <- function(A, B) {
  if (nrow(A) != nrow(B) || ncol(A) != ncol(B)) {
    stop("Las dimensiones de las matrices no coinciden.")
  }
  suma <- matrix(NA, nrow(A), ncol(A))
  for (i in 1:nrow(A)) {
    for (j in 1:ncol(A)) {
      suma[i, j] <- A[i, j] + B[i, j]
    }
  }
  return(suma)
}

Ejercicio 8

  1. Mínimo de una matriz y su posición.

    #' Mínimo de una matriz y su posición
    #'
    #' Esta función recorre una matriz y devuelve un vector con el valor mínimo 
    #' y su posición (fila y columna) dentro de la matriz.
    #'
    #' @param m Una matriz numérica.
    #'
    #' @return Un vector numérico de longitud 3 con los siguientes valores: 
    #' - Posición 1: El valor mínimo encontrado en la matriz.
    #' - Posición 2: La fila donde se encuentra el valor mínimo.
    #' - Posición 3: La columna donde se encuentra el valor mínimo.
    #'
    #' @examples
    #' matriz <- matrix(c(3, 2, 5, 1, 4, 6), nrow = 2)
    #' minimo_matriz(matriz)
    minimo_matriz <- function(m) {
      min <- m[1, 1]
      fila <- 1
      col <- 1
      for (i in 1:nrow(m)) {
        for (j in 1:ncol(m)) {
          if (m[i, j] < min) {
            min <- m[i, j]
            fila <- i
            col <- j
          }
        }
      }
      resultado <- c(minimo = min, fila = fila, columna = col)
      return(resultado)
    }
  2. Encontrar el valor mínimo en una fila específica de una matriz.

    #' Encontrar el valor mínimo en una fila específica de una matriz
    #'
    #' Esta función busca el valor mínimo dentro de una fila específica de una 
    #' matriz y devuelve el valor junto con el número de columna donde se 
    #' encuentra.
    #'
    #' @param m Una matriz numérica.
    #' @param fila Un entero que indica el número de fila en la que se desea 
    #' buscar el valor mínimo.
    #'
    #' @return Un vector numérico de longitud 2con los siguientes valores: 
    #' - Posición 1: El valor mínimo en la fila especificada.
    #' - Posición 2: El número de columna donde se encuentra ese valor mínimo.
    #'
    #' @examples
    #' matriz <- matrix(c(3, 2, 5, 1, 4, 6), nrow = 2)
    #' minimo_matriz_fila(matriz, 1)
    minimo_matriz_fila <- function(m, fila = 1) {
      min <- m[fila, 1]
      col <- 1
      for (j in 1:ncol(m)) {
        if (m[fila, j] < min) {
          min <- m[fila, j]
          col <- j
        }
      }
      return(c(minimo = min, columna = col))
    }

Ejercicio 9

  1. Ordenar matriz por columna en orden descendente.

    #' Ordenar matriz por columna en orden descendente
    #'
    #' Esta función ordena las filas de una matriz numérica según los valores
    #' de una columna específica, en orden descendente.
    #'
    #' @param m Una matriz
    #' @param col Un entero que indica el índice de la columna por la que se 
    #' desea ordenar.
    #'
    #' @return La matriz ordenada por la columna especificada en orden 
    #' descendente.
    #' 
    #' @examples
    #' m <- matrix(c(1, 2, 3, 4, 5, 6), ncol = 2, byrow = TRUE)
    #' ordenar_desc_col(m, 1)
    ordenar_desc_col <- function(m, col) {
      if (nrow(m) > 1) {
        for (i in 1:(nrow(m)-1)) {
          for (j in (i+1):nrow(m)) {
            if (m[i, col] < m[j, col]) {
              for (k in 1:ncol(m)) {
                tmp <- m[i, k]
                m[i, k] <- m[j, k]
                m[j, k] <- tmp
              }
            }
          }
        }
      }
      return(m)
    }

    Observaciones

    • En lugar de chequear si tiene más de una fila, podríamos directamente poner for (i in 1:nrow(m)) y for (j in i:nrow(m)). Esto funciona también cuando la matriz provista tiene una sola fila, pero en cualquier otro caso implica a hacer comparaciones lógicas de más, tantas como número de filastenga la matriz.
    • Se puede mejorar la función agregando un control para que el argumento col provisto por el usuario esté siempre entre 1 y ncol(m).
  2. Ordenar matriz por fila en orden ascendente.

    #' Ordenar matriz por fila en orden ascendente
    #'
    #' Esta función ordena las columnas de una matriz numérica según los valores
    #' de una fila específica, en orden ascendente.
    #'
    #' @param m Una matriz numérica.
    #' @param fila Un entero que indica el índice de la fila por la que se desea 
    #' ordenar.
    #'
    #' @return La matriz ordenada por la fila especificada en orden ascendente.
    #' 
    #' @examples
    #' m <- matrix(c(3, 1, 4, 2, 6, 5), nrow = 2, byrow = TRUE)
    #' ordenar_asc_fila(m, 1)
    ordenar_asc_fila <- function(m, fila) {
      if (ncol(m) > 1) {
        for (i in 1:(ncol(m) - 1)) {
          for (j in (i + 1):ncol(m)) {
            if (m[fila, i] > m[fila, j]) { # Solo cambia el signo
              for (k in 1:nrow(m)) {
                tmp      <- m[k, i]
                m[k, i]  <- m[k, j]
                m[k, j]  <- tmp
              }
            }
          }
        }
      }
      return(m)
    }

Ejercicio 10

#' Verificar si una matriz es un cuadrado mágico
#'
#' Esta función verifica si una matriz cuadrada numérica es un cuadrado mágico.
#' Un cuadrado mágico es una matriz en la que la suma de los elementos en cada 
#' fila, en cada columna y en las dos diagonales principales es igual.
#'
#' @param cuadrado Una matriz cuadrada numérica.
#'
#' @return `TRUE` si la matriz es un cuadrado mágico, `FALSE` en caso contrario.
#' 
#' @examples
#' m <- matrix(c(2, 7, 6, 9, 5, 1, 4, 3, 8), nrow=3, byrow=TRUE)
#' cuadrado_magico(m)
cuadrado_magico <- function(cuadrado) {
  n <- nrow(cuadrado)
  
  # Calcular el primer total fila para tener de control
  control <- 0
  for (j in 1:n) {
    control <- control + cuadrado[1, j]
  }
  
  # Calcular los restantes totales filas y chequearlos
  for (i in 2:n) {
    total <- 0
    for (j in 1:n) {
      total <- total + cuadrado[i, j]
    }
    if (total != control) {
      return(FALSE)
    }
  }
  
  # Chequear totales columnas si lo anterior estuvo bien
  for (j in 1:n) {
    total <- 0
    for (i in 1:n) {
      total <- total + cuadrado[i, j]
    }
    if (total != control) {
      return(FALSE)
    }
  }
  
  # Chequear diagonales si lo anterior estuvo bien
  diag1 <- 0
  diag2 <- 0
  for (i in 1:n) {
    diag1 <- diag1 + cuadrado[i, i]
    diag2 <- diag2 + cuadrado[n - i + 1, i]
  }
  if (diag1 != control || diag2 != control) {
    return(FALSE)
  }
  
  # Si llegamos hasta acá es porque todos los controles dieron bien
  return(TRUE)
}

Operaciones vectorizadas

Ejercicio 11

x <- c(2, 5, 8, 1, 9)
x
[1] 2 5 8 1 9
# a)
log(x, base = 5)
[1] 0.4306766 1.0000000 1.2920297 0.0000000 1.3652124
# b)
which(x > 4)
[1] 2 3 5
# c)
x[x>4]
[1] 5 8 9
# d)
length(x[x>4])
[1] 3
sum(x>4)
[1] 3
# e)
x[x %% 2 == 0]
[1] 2 8
# f)
sum(x[x>5])
[1] 17

Ejercicio 12

m <- matrix(1:9, nrow = 3)
m
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
# a)
m + 10
     [,1] [,2] [,3]
[1,]   11   14   17
[2,]   12   15   18
[3,]   13   16   19
# b)
m^(1/3)
         [,1]     [,2]     [,3]
[1,] 1.000000 1.587401 1.912931
[2,] 1.259921 1.709976 2.000000
[3,] 1.442250 1.817121 2.080084
# c)
m * 2
     [,1] [,2] [,3]
[1,]    2    8   14
[2,]    4   10   16
[3,]    6   12   18
# d)
n <- matrix(9:1, nrow = 3)
m - n
     [,1] [,2] [,3]
[1,]   -8   -2    4
[2,]   -6    0    6
[3,]   -4    2    8
# e)
sum(m > 5)
[1] 4
# f)
m[m > 5]  # muestra los valores mayores que 5 como un vector
[1] 6 7 8 9
# g)
which(m > 5, arr.ind = TRUE)
     row col
[1,]   3   2
[2,]   1   3
[3,]   2   3
[4,]   3   3
# h)
sum(m)
[1] 45
mean(m)
[1] 5
rowSums(m)
[1] 12 15 18
colSums(m)
[1]  6 15 24
rowMeans(m)
[1] 4 5 6
colMeans(m)
[1] 2 5 8

Ejercicio 13

x <- 1:20
# a)
x[x > 10 & x %% 3 == 0]
[1] 12 15 18
# b)
x[!(x %% 2 == 0 | x %% 5 == 0)]
[1]  1  3  7  9 11 13 17 19
x[x %% 2 != 0 & x %% 5 != 0]
[1]  1  3  7  9 11 13 17 19
# c)
length(x[x %% 2 != 0 & x %% 5 != 0])
[1] 8
sum(x %% 2 != 0 & x %% 5 != 0)
[1] 8

Ejercicio 14

  1. La función es sum(). Se puede usar tanto con vectores como con matrices.

    mi_vector <- c(60, -5, 0, 12, 1)
    # Nuestra función
    suma(mi_vector)
    [1] 68
    # La función de R Base
    sum(mi_vector)
    [1] 68
  2. Basta con hacer:

    u <- c(5, 8, 2)
    v <- c(2, 3, -1)
    u + v
    [1]  7 11  1
    A <- matrix(c(5, 8, 2, 2, 3, 1), nrow = 3)
    B <- matrix(c(0, -1, 3, 1, 2, 4), nrow = 3)
    A + B
         [,1] [,2]
    [1,]    5    3
    [2,]    7    5
    [3,]    5    5
  3. La función es sort()

    mi_vector <- c(60, -5, 0, 12, 1)
    # Por defecto, sort() ordena de forma ascendente
    sort(mi_vector)
    [1] -5  0  1 12 60
    # Podemos definir decreasing = TRUE para ordenar en forma descendente
    sort(mi_vector, decreasing = TRUE)
    [1] 60 12  1  0 -5

    Si se aplica en vectores de tipo carácter, ordena alfabéticamente:

    mi_vector <- c("introducción", "a", "la", "programación")
    sort(mi_vector)
    [1] "a"            "introducción" "la"           "programación"
    sort(mi_vector, decreasing = TRUE)
    [1] "programación" "la"           "introducción" "a"           
  4. Usamos min() y max():

    # Vectores
    mi_vector <- c(60, -5, 0, -5, 12, 1)
    min(mi_vector)
    [1] -5
    max(mi_vector)
    [1] 60
    # Ubicación del mínimo o máximo (sólo primera ocurrencia)
    which.min(mi_vector)
    [1] 2
    which.max(mi_vector)
    [1] 1
    # Ubicación del mínimo o máximo (todas las ocurrencias)
    which(mi_vector == min(mi_vector))
    [1] 2 4
    which(mi_vector == max(mi_vector))
    [1] 1
    # También sirve para vectores de tipo carácter
    mi_vector <- c("introducción", "a", "la", "programación")
    min(mi_vector)
    [1] "a"
    # Matrices
    A <- matrix(c(5, 8, 2, 7, 3, 1), nrow = 3)
    A
         [,1] [,2]
    [1,]    5    7
    [2,]    8    3
    [3,]    2    1
    min(A)
    [1] 1
    max(A)
    [1] 8
    # Posición (arr.ind = TRUE para que nos indique fila y columna)
    which(A == min(A), arr.ind = TRUE)
         row col
    [1,]   3   2
    which(A == max(A), arr.ind = TRUE)
         row col
    [1,]   2   1
  5. Se puede hacer:

    u <- c(5, 8, 2)
    v <- c(2, 3, -1)
    sum(u * v)
    [1] 32
    # Usando la function del Ejercicio 5a:
    prod_escalar(u, v)
    [1] 32
  6. De la siguiente forma:

    A
         [,1] [,2]
    [1,]    5    7
    [2,]    8    3
    [3,]    2    1
    # Evaluamos min() sólo en la fila 3
    min(A[3, ])
    [1] 1
    # Para saber en qué columna de la fila 3 se encuentra su mínimo:
    which.min(A[3, ])
    [1] 2
    # Con la función del ejecicio 8b
    minimo_matriz_fila(A, 3)
     minimo columna 
          1       2 
  7. Una posibilidad es:

    cuadrado_magico <- function(cuadrado) {
    
      # Todos las sumas
      sumas_filas <- rowSums(cuadrado)
      sumas_col <- colSums(cuadrado)
      suma_diag1 <- sum(diag(cuadrado))
      suma_diag2 <- sum(diag(cuadrado[nrow(cuadrado):1, ]))
    
      # Junto las sumas en un vector, deberían ser todoas iguales
      # Arbitrariamente dejo afuera a suma_diag2, para comparar con ella
      sumas <- c(sumas_filas, sumas_col, suma_diag1)
    
      # ¿Dieron igual todas las sumas?
      return(all(sumas == suma_diag2))
    }
    
    cuadrado <- matrix(c(16,  3,  2, 13,
                          5, 10, 11,  8,
                          9,  6,  7, 12,
                          4, 15, 14,  1), nrow = 4, byrow = TRUE)
    cuadrado_magico(cuadrado)
    [1] TRUE
    cuadrado <- matrix(c( 0,  3,  2, 13,
                          5, 10, 11,  8,
                          9,  6,  7, 12,
                          4, 15, 14,  1), nrow = 4, byrow = TRUE)
    cuadrado_magico(cuadrado)
    [1] FALSE

Listas, funciones apply() y más

Ejericico 15

  1. mi_lista <- list(
      numeros = 1:10,
      letras = LETTERS,
      matriz = matrix(0, nrow = 2, ncol = 2),
      lista_anidada = list(
          valores_logicos = c(TRUE, FALSE),
          mi_texto = "¡Ayuda! Estoy dentro de una lista anidada."
        )
    )
  2. mi_lista$lista_anidada$mi_texto
    [1] "¡Ayuda! Estoy dentro de una lista anidada."
  3. length(mi_lista)
    [1] 4

Ejercicio 16

a <- c(2, 1, 9)
b <- c("X", "Y", "Z")
d <- list(b, a)
  1. d[[2]]
    [1] 2 1 9
  2. d[[1]][1] <- "M"
    d
    [[1]]
    [1] "M" "Y" "Z"
    
    [[2]]
    [1] 2 1 9
  3. # Creación de la lista
    mi_lista <- list(1:10, "Buenas", TRUE)
    mi_lista
    [[1]]
     [1]  1  2  3  4  5  6  7  8  9 10
    
    [[2]]
    [1] "Buenas"
    
    [[3]]
    [1] TRUE
    # De manera vectorizada le sumamos 2 a cada elemento del vector y lo 
    # guardamos en el mismo lugar
    mi_lista[[1]] <- mi_lista[[1]] + 2
    
    # Cambiar el TRUE por FALSE
    mi_lista[[3]] <- FALSE
    mi_lista
    [[1]]
     [1]  3  4  5  6  7  8  9 10 11 12
    
    [[2]]
    [1] "Buenas"
    
    [[3]]
    [1] FALSE

Ejercicio 17

#' Cociente de la división de números naturales
#' 
#' @description
#' Calcula el cociente entero y el resto en la división de dos números naturales.
#'
#' @details 
#' La función devuelve una lista con el dividendo, divisor, cociente, resto y 
#' un valor lógico que indica si el divisor es divisor exacto del dividendo.
#' 
#' @param dividendo,divisor Números naturales.
#'
#' @return Una lista con los valores: dividendo, divisor, cociente, resto, y es_divisor.
#'
#' @examples
#' cociente(1253, 4)
#' cociente(3, 4)
cociente <- function(dividendo, divisor) {
  resto <- dividendo
  coc <- 0
  while (resto >= divisor) {
    coc <- coc + 1
    resto <- resto - divisor
  }
  es_divisor <- resto == 0
  
  return(
    list(
      dividendo = dividendo,
      divisor = divisor,
      cociente = coc,
      resto = resto,
      es_divisor = es_divisor
    )
  )
}

Ejercicio 18

  1. set.seed(34)
    m <- matrix(sample(100, 20), nrow = 4)
    m
         [,1] [,2] [,3] [,4] [,5]
    [1,]   93   50   29   80   20
    [2,]   33    8   11   61   99
    [3,]    9   86   48   67  100
    [4,]   10   54   44   43   46
    # Crear vector para guardar los promedios
    promedios <- numeric(ncol(m))
    # Calcular iterando a través de las filas
    for (j in 1:ncol(m)) {
      promedios[j] <- mean(m[, j])
    }
    promedios
    [1] 36.25 49.50 33.00 62.75 66.25
  2. apply(m, 2, mean)
    [1] 36.25 49.50 33.00 62.75 66.25

Ejercicio 19

  1. A <- matrix(seq(1, 100, length.out = 9), ncol = 3)

  2. B <- matrix(rep(1:3 * 5, 3), ncol = 3)

  3. C <- matrix(rep(1:2 * 4, each = 6), ncol = 2)

  4. AB <- rbind(A, B)

  5. ABC <- cbind(AB, C)

Ejercicio 20

  1. stock_frutas <- list(
      naranjas = 10,
      manzanas = 15,
      peras = 5
    )
  2. stock_verduras <- list(
      tomates = 8,
      cebollas = 12
    )
  3. stock_verduleria <- list(
      frutas = stock_frutas,
      verduras = stock_verduras
    )
  4. # Usando el operador "$"
    stock_verduleria$verduras$zanahorias <- 10
    
    # Usando la función append()
    stock_verduleria$verduras <- append(stock_verduleria$verduras, list(zanahorias = 10))

Ejercicio 21

  1. Lectura del archivo para cargar los objetos que contiene en el ambiente global. Recordar que si el archivo no se encuentra en el working directory, se debe especificar la ruta informática completa o cambiarlo.

    load("popurri.RData")

    Hay 5 objetos:

    • cosa1: vector numérico de largo 3

    • cosa2: vector carácter de largo 5

    • cosa3: matriz numérica de dimensión 10x3

    • cosa4: lista con 4 elementos:

      • 1° elemento, con nombre “letras”: matriz carácter de dimensión 3x6
      • 2° elemento, con nombre “mediciones”: vector numérico de largo 10
      • 3° elemento, con nombre “respuestas”: vector lógico de largo 6
      • 4° elemento, con nombre “numeros”: matriz numérica de dimensión 10x10
    • cosa5: lista con 5 elementos, todos ellos vectores numéricos de distinto largo.

  2. cosa1
    [1] 0.85659039 0.01082598 0.55285632
    names(cosa1) <- c("valorA", "valorB", "valorC")
    cosa1
        valorA     valorB     valorC 
    0.85659039 0.01082598 0.55285632 
  3. cosa1[3]        # Indexando según posición
       valorC 
    0.5528563 
    cosa1["valorC"] # Indexando según nombre
       valorC 
    0.5528563 
  4. cosa4[[2]]            # Indexando según posición
     [1]  1.08915250  0.76896317 -0.06656841  1.06452895  0.08372996  0.72989718
     [7]  0.14348919  1.08879924 -0.97206064 -1.39850426
    cosa4[["mediciones"]] # Indexando según nombre (1)
     [1]  1.08915250  0.76896317 -0.06656841  1.06452895  0.08372996  0.72989718
     [7]  0.14348919  1.08879924 -0.97206064 -1.39850426
    cosa4$mediciones      # Indexando según nombre (2)
     [1]  1.08915250  0.76896317 -0.06656841  1.06452895  0.08372996  0.72989718
     [7]  0.14348919  1.08879924 -0.97206064 -1.39850426
  5. sort(cosa4$mediciones)
     [1] -1.39850426 -0.97206064 -0.06656841  0.08372996  0.14348919  0.72989718
     [7]  0.76896317  1.06452895  1.08879924  1.08915250
  6. t(cosa4$numeros)
         [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
    [1,]  883   18  139   30  487  887  787  261  852   532
    [2,]  435  714  903  932  967  658   44  138  476   630
    [3,]  940  894  872  783   71  211   37  103  115   208
  7. min(cosa4$numeros)
    [1] 18
    apply(cosa4$numeros, 2, max)
    [1] 887 967 940
  8. x <- seq(1, 100, length.out = 9)
  9. y <- matrix(x, nrow = 3)
  10. z <- rbind(cosa4$numeros, y)
  11. w <- c(cosa1, cosa4$numeros, cosa1)
    names(w) <- NULL
    w
     [1]   0.85659039   0.01082598   0.55285632 883.00000000  18.00000000
     [6] 139.00000000  30.00000000 487.00000000 887.00000000 787.00000000
    [11] 261.00000000 852.00000000 532.00000000 435.00000000 714.00000000
    [16] 903.00000000 932.00000000 967.00000000 658.00000000  44.00000000
    [21] 138.00000000 476.00000000 630.00000000 940.00000000 894.00000000
    [26] 872.00000000 783.00000000  71.00000000 211.00000000  37.00000000
    [31] 103.00000000 115.00000000 208.00000000   0.85659039   0.01082598
    [36]   0.55285632
  12. lapply() devuelve los resultados en una lista y sapply() en un vector.

    # Con una estructura for
    maximos <- numeric(length(cosa5))
    for (i in 1:length(cosa5)) {
      maximos[i] <- max(cosa5[[i]])
    }
    maximos
    [1] 1.363091 1.083697 1.002246 1.387853 1.713647
    # Con lapply
    lapply(cosa5, max)
    [[1]]
    [1] 1.363091
    
    [[2]]
    [1] 1.083697
    
    [[3]]
    [1] 1.002246
    
    [[4]]
    [1] 1.387853
    
    [[5]]
    [1] 1.713647
    # Con sapply
    sapply(cosa5, max)
    [1] 1.363091 1.083697 1.002246 1.387853 1.713647
  13. Se aplica la función max() a cada elemento de la lista cosa4. En el vector letras obtuvo el “máximo” al ordenar los datos de tipo carácter alfabeticamente. En el vector mediciones obtuvo el máximo valor numérico. En el vector de valores lógicos respuestas el máximo fue 1 porque los valores FALSE son considerados como 0 y los TRUE como 1. En la matriz numeros obtuvo el máximo valor en toda la matriz.

    sapply(cosa4, max)
                letras         mediciones         respuestas            numeros 
                   "Z" "1.08915250302242"                "1"              "967" 
  14. Se aplica la función sqrt() a cada elemento de la lista cosa4, pero como hay elementos que no tienen datos numéricos, como el vector carácter letras, tratar de sacarles la raiz cuadrada produce un error.

    lapply(cosa4, sqrt)
    Error in FUN(X[[i]], ...) : non-numeric argument to mathematical function
  15. Se obtiene un vector lógico del mismo largo con un TRUE en cada posición donde hay un número mayor a cero y FALSE en caso contrario.

    cosa4$mediciones > 0
     [1]  TRUE  TRUE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE
  16. cosa4$mediciones[cosa4$mediciones > 0]
    [1] 1.08915250 0.76896317 1.06452895 0.08372996 0.72989718 0.14348919 1.08879924
  17. v <- abs(cosa3) < 1
    v
           [,1]  [,2]  [,3]
     [1,] FALSE  TRUE  TRUE
     [2,] FALSE  TRUE  TRUE
     [3,]  TRUE FALSE  TRUE
     [4,] FALSE  TRUE  TRUE
     [5,]  TRUE  TRUE  TRUE
     [6,]  TRUE  TRUE  TRUE
     [7,]  TRUE  TRUE  TRUE
     [8,]  TRUE  TRUE FALSE
     [9,]  TRUE  TRUE  TRUE
    [10,] FALSE  TRUE  TRUE
  18. En R los valores lógicos TRUE son evaluados como 1 y los FALSE como 0. Por eso al aplicarle la suma a una matriz de valores lógicos se obtiene la cantidad de valores TRUE. Luego, sum(v) nos dice cuántos valores en la matriz cosa3 tienen valor absoluto menor que 1. apply(v, 1, sum) indica cuántos TRUE hay en cada fila, mientras que apply(v, 2, sum), cuántos TRUE hay en cada columna.

    sum(v)
    [1] 24
    apply(v, 1, sum)
     [1] 2 2 2 2 3 3 3 2 3 2
    apply(v, 2, sum)
    [1] 6 9 9
  19. w
     [1]   0.85659039   0.01082598   0.55285632 883.00000000  18.00000000
     [6] 139.00000000  30.00000000 487.00000000 887.00000000 787.00000000
    [11] 261.00000000 852.00000000 532.00000000 435.00000000 714.00000000
    [16] 903.00000000 932.00000000 967.00000000 658.00000000  44.00000000
    [21] 138.00000000 476.00000000 630.00000000 940.00000000 894.00000000
    [26] 872.00000000 783.00000000  71.00000000 211.00000000  37.00000000
    [31] 103.00000000 115.00000000 208.00000000   0.85659039   0.01082598
    [36]   0.55285632
    w[w > 500] <- -100
    w
     [1]    0.85659039    0.01082598    0.55285632 -100.00000000   18.00000000
     [6]  139.00000000   30.00000000  487.00000000 -100.00000000 -100.00000000
    [11]  261.00000000 -100.00000000 -100.00000000  435.00000000 -100.00000000
    [16] -100.00000000 -100.00000000 -100.00000000 -100.00000000   44.00000000
    [21]  138.00000000  476.00000000 -100.00000000 -100.00000000 -100.00000000
    [26] -100.00000000 -100.00000000   71.00000000  211.00000000   37.00000000
    [31]  103.00000000  115.00000000  208.00000000    0.85659039    0.01082598
    [36]    0.55285632