Часть 1

  1. Напишите код, который запрашивает у пользователя его имя и фамилию (отдельные строки “Enter your name:” и “Enter your surname:”), сохраняет их и выводит на экран “Hello, [name] [surname]! Welcome to R!”
name <- readline("Enter your name: ")
## Enter your name:
surname <- readline("Enter your surname: ")
## Enter your surname:
print(sprintf("Hello, %s %s! Welcome to R!", name, surname))
## [1] "Hello,  ! Welcome to R!"
  1. Напишите код, который сохраняет число, которое ввел пользователь с клавиатуры (предполагается, что пользователь вводит только числа, причем в правильном формате - в качестве разделителя использует точку), в переменную x и если x является целым числом, то выводит на экран сообщение “It is an integer.”, а если x не является таковым, то выводит “It is not an integer”.
x <- readline("Enter a number: ")
if (as.numeric(x) == as.integer(x)){print("It is an integer.")} else{
  print("It is not an integer.")
}
  1. Напишите код, который запрашивает у пользователя число элементов вектора (“Enter number of elements:”), сохраняет его в переменную n и создает вектор заданной длины, состоящий из пропущенных значений.
n <- readline("Enter number of elements: ")
n <- as.integer(n)
d <- rep(NA, n)
  1. Напишите код, который запрашивает у пользователя число элементов вектора (“Enter number of elements:”), сохраняет его в переменную n и создает вектор заданной длины, состоящий из пропущенных значений. Дальше, если индекс элемента четный, то этот элемент заменяется на 1, если нечетный - на 0.
n <- readline("Enter number of elements: ")
n <- as.integer(n)
d <- rep(NA, n)
s <- 1:length(d)
# s <- 1:n
for (i in s){
  if (i %% 2 == 0){d[i] <- 1}
  else{d[i] <- 0}
}
  1. Дан вектор оценок студентов grades10 (оценки указаны в 10-балльной шкале). Напишите код, который на основе вектора grades10 создает вектор grades5 - вектор оценок в 5-балльной шкале:
grades10 <- c(1, 4, 7, 8, 4, 3, 10, 9)
n <- length(grades10)
grades5 <- rep(NA, n)
indices <- 1:n
for (i in indices){
  if (grades10[i] == 0){grades5[i] <- 1}
  if (grades10[i] > 0 & grades10[i] < 4){grades5[i] <- 2}
  if (grades10[i] >= 4 & grades10[i] <= 5){grades5[i]<-3}
  if (grades10[i] >= 6 & grades10[i] <=7){grades5[i] <-4}
  if (grades10[i] >= 8){grades5[i] <- 5}
}
  1. Напишите код, который запрашивает у пользователя размерность матрицы (предполагается, что пользователь вводит число строк и столбцов через пробел), сохраняет их и создает единичную матрицу заданной размерности. Если невозможно создать единичную матрицу заданной размерности, на экран выводится сообщение “Impossible to create an identity matrix with such dimensions.”.

Подсказка: единичная матрица - квадратная матрица (число строк равно числу столбцов), на главной диагонали которой стоят 1, а все остальные элементы равны 0. Пример:

[1 0 0]
[0 1 0]
[0 0 1]

Решение 1 (не знаем про diag())

dims <- readline("Enter dimensions: ")
dims_vector <- as.integer(unlist(strsplit(dims, " ")))
nrows <- dims_vector[1]
ncols <- dims_vector[2]
if (nrows != ncols){print("Impossible to create an identity matrix with such dimensions.")} else{
  M <- matrix(0, nrows, ncols)
  for (i in 1:nrows){
    for (j in 1:ncols){
      if (i == j){
        M[i,j] <- 1
      }
    }
  }
    }

Решение 2 (знаем про diag())

dims <- readline("Enter dimensions: ")
dims_vector <- as.integer(unlist(strsplit(dims, " ")))
nrows <- dims_vector[1]
ncols <- dims_vector[2]
if (nrows != ncols){
  print("Impossible to create an identity matrix with such dimensions.")} else{
  M <- matrix(0, nrows, ncols)
  diag(M) <- 1
  }
  1. Дан вектор стран:
cnt <- c('France', 'Hungary', 'Ukraine', 'Romania', 'Germany', 'Russia', 'Finland', 'Italy', 'Spain')

Напишите код, который перебирает элементы вектора cnt до тех пор, пока не дойдет до России. Если название страны отлично от ‘Russia’, на экран должно выводиться сообщение “It is not Russia.”, а если название совпадает с ‘Russia’, на экран должно выводиться сообщение: “Russia is found. Its number is n”, где n - порядковый номер России в списке.

а) Используйте цикл for.

cnt <- c('France', 'Hungary', 'Ukraine', 'Romania', 'Germany', 'Russia', 'Finland', 'Italy', 'Spain')
for (c in cnt){
  if (c == "Russia"){
    print(sprintf("Russia is found. Its number is %i", which(cnt == "Russia")))
    break
  } else {
    print("It is not Russia.")
  }
}
## [1] "It is not Russia."
## [1] "It is not Russia."
## [1] "It is not Russia."
## [1] "It is not Russia."
## [1] "It is not Russia."
## [1] "Russia is found. Its number is 6"

б) используйте цикл while.

i <- 1
c <- cnt[i]
while (c != 'Russia'){
  i <- i + 1
  c <- cnt[i]
  print("It is not Russia.")
}
## [1] "It is not Russia."
## [1] "It is not Russia."
## [1] "It is not Russia."
## [1] "It is not Russia."
## [1] "It is not Russia."
print(sprintf("Russia is found. Its number is %i", 
              which(cnt == "Russia")))
## [1] "Russia is found. Its number is 6"

Часть 2

  1. Напишите функцию, которая просит пользователя ввести свое имя, и если оно совпадает Вашим, выводит на экран “[Name], welcome to R! I missed you.”, если не совпадает, то выводит на экран “Sorry, R is not available now.”. Подразумевается, что R знает Ваше имя (при желании можете написать функцию, которая вытаскивает Ваше имя пользователя на компьютере и сравнивает с ним).
welcome <- function(){
  name <- readline("Enter your name: ")
  if (name == "Alla"){print(sprintf("%s, welcome to R! I missed you.", name))}
  else print("Sorry, R is not available now.")
}

Могли бы вывести имя пользователя в системе (можно проще, но хочется еще раз повторить strsplit()):

welcome <- function(){
  wd <- getwd()
  name <- unlist(strsplit(wd, "/"))[2]
  attempt <- readline("Enter your name: ")
  if (attempt == name){print(sprintf("%s, welcome to R! I missed you.", name))}
  else print("Sorry, R is not available now.")
}
  1. Напишите функцию, которая принимает на вход числовой вектор и возвращает вектор, состоящий из квадратов элементов вектора, поданного на вход. Можете для определенности назвать функцию get_squares.
get_squares <- function(vec){
  return(vec^2)
}
w <- c(-1, 4, 6, 10)
get_squares(w)
## [1]   1  16  36 100
  1. Напишите функцию smart_squares, которая принимает на вход вектор, и если он числовой, то возвращает вектор из квадратов его элементов, а если нет – возвращает вектор из пропущенных значений и выводит на экран сообщение “Your vector is not numeric.”
smart_squares <- function(vec){
  if (is.character(vec) == TRUE){
    result <- rep(NA, length(vec))
    print("Your vector is not numeric.")}
  else{
    result <- vec^2
  }
  return(result)
}
smart_squares(c(2, 4, 5))
## [1]  4 16 25
smart_squares(c("6", "5"))
## [1] "Your vector is not numeric."
## [1] NA NA
  1. Напишите функцию, которая принимает на вход базу данных, удаляет в ней пропущенные значения и выводит на экран описательные статистики по всем переменным. Для тестирования можете взять любую базу данных, например, с наших семинаров.
SumData <- function(df){
  df <- na.omit(df)
  summary(df)
}
SumData(mtcars)
##       mpg             cyl             disp             hp       
##  Min.   :10.40   Min.   :4.000   Min.   : 71.1   Min.   : 52.0  
##  1st Qu.:15.43   1st Qu.:4.000   1st Qu.:120.8   1st Qu.: 96.5  
##  Median :19.20   Median :6.000   Median :196.3   Median :123.0  
##  Mean   :20.09   Mean   :6.188   Mean   :230.7   Mean   :146.7  
##  3rd Qu.:22.80   3rd Qu.:8.000   3rd Qu.:326.0   3rd Qu.:180.0  
##  Max.   :33.90   Max.   :8.000   Max.   :472.0   Max.   :335.0  
##       drat             wt             qsec             vs        
##  Min.   :2.760   Min.   :1.513   Min.   :14.50   Min.   :0.0000  
##  1st Qu.:3.080   1st Qu.:2.581   1st Qu.:16.89   1st Qu.:0.0000  
##  Median :3.695   Median :3.325   Median :17.71   Median :0.0000  
##  Mean   :3.597   Mean   :3.217   Mean   :17.85   Mean   :0.4375  
##  3rd Qu.:3.920   3rd Qu.:3.610   3rd Qu.:18.90   3rd Qu.:1.0000  
##  Max.   :4.930   Max.   :5.424   Max.   :22.90   Max.   :1.0000  
##        am              gear            carb      
##  Min.   :0.0000   Min.   :3.000   Min.   :1.000  
##  1st Qu.:0.0000   1st Qu.:3.000   1st Qu.:2.000  
##  Median :0.0000   Median :4.000   Median :2.000  
##  Mean   :0.4062   Mean   :3.688   Mean   :2.812  
##  3rd Qu.:1.0000   3rd Qu.:4.000   3rd Qu.:4.000  
##  Max.   :1.0000   Max.   :5.000   Max.   :8.000
  1. Напишите функцию, которая принимает на вход путь к папке, в которой лежит база данных (например, “C:/Users/my-folder”) и название файла с базой данных (считайте, что все хранится в csv-формате), и возвращает вектор, содержащий следующую информацию: число переменных в базе, число наблюдений в базе, количество строк, включающих пропущенные значения.

Примечание: для более user-friendly выдачи можно вспомнить про поименованные векторы.

SumData2 <- function(path, filename){
  full_path <- paste(path, filename, sep = "")
  df <- read.csv(full_path)
  nobs <- dim(df)[1]
  nvars <- dim(df)[2]
  n.na.rows <- sum(!complete.cases(df))
  result <- c(observations = nobs, 
              variables = nvars,
              rows_with_na = n.na.rows)
  return(result)
}

Для проверки соберем маленькую базу вручную:

A <- c(18, 22, 33, 19, 45, NA, 48, NA)
B <- rep(c(0, 1), 4)
C <- c(1, 4, 7, NA, 9, 0, 0, 1)
data <- as.data.frame(cbind(A, B, C))
data
write.csv(data, "/home/oem/Dropbox/my_data.csv")

# проверяем - указываем путь и название файла
SumData2("/home/oem/Dropbox/", "my_data.csv")