3 Tool: The R Language (Environment) 3.1 Diversity of Programs for Statistical Analysis We have begun the study of biological statistics. It can be organized in two different ways. In the first approach (which may be called "ab ovo"), students are taught the mathematical foundations of the methods under study, the necessary formulas are derived, and the theorems explaining them are proved. If a student has mastered such a course, solving specific problems associated with a particular dataset in their field of research proves to be a manageable task. The second approach ("do as I do") consists of showing students how to solve typical problems using one or another set of tools. The first approach is more demanding. People who have successfully completed training via the first approach have a higher level of preparation and are more versatile. However, to a significant extent, the first approach operates on an "all or nothing" principle. Either you have mastered the fundamental approaches and can apply them, or you do not know what to do and become lost when faced with the simplest tasks. The second approach is more "democratic" and allows for easy solutions to typical problems. Unfortunately, without understanding the foundations of the methods, people who have been taught to repeat certain sequences of actions without having their meaning explained often make errors. Another drawback of the second approach is habituation to specific programs (tools for solving typical tasks). Naturally, different categories of students require either the first, the second, or a combination of both approaches. Experience teaching statistics to biology students indicates that, most often, the "do as I do" approach proves more beneficial for them. Implementing the "do as I do" approach requires selecting the programs with which the instruction will be conducted. Here one must choose among six categories of programs. — Free amateur and semi-professional programs; there are many of these, but none of them are universal, and moreover, almost each one requires its own approach (although some solutions should be recognized as successful, such as this set of online calculators); — Specialized free programs for solving a certain range of tasks. Arguably the leader in this category is the PAST program, which runs exclusively in the Windows environment. PAST was created by paleontology specialists as a "Statistica for the poor" — a simplified and free analogue of the costly Statistica package. The latest version of PAST and its user manuals can be downloaded here; — Paid or free software not specifically designed for solving statistical tasks but capable of providing broad capabilities for working with data, including their statistical analysis. This category includes Excel and Access, components of Microsoft Office. If work with spreadsheets is required, we recommend using LibreOffice Calc, a free analogue of Excel that is superior to it in many respects. As noted above, spreadsheets are often used for data collection, but... "It should be noted here that under no circumstances is it recommended to conduct any statistical analysis in spreadsheet programs. Not to mention that the internet is simply saturated with articles about errors in these programs and/or in their statistical modules, it is also ideologically fundamentally wrong. In other words: Use R!". A. B. Shipunov, E. M. Baldin — Specialized paid programs designed for solving a specific set of tasks. There are two market leaders in this field. SPSS (Statistical Package for the Social Sciences) is a program widely used in the humanities. In 2009, the renowned IBM corporation acquired SPSS Inc. Their product is now called PASW Statistics (Predictive Analytics SoftWare). Among natural scientists, especially in the post-Soviet space, the Statistica package developed by StatSoft has gained particular popularity. — Paid programming languages that permit diverse applications. The leader in this field is SAS (Statistical Analysis System), a programming language and corresponding program from SAS Institute. This software product is designed primarily for serious business, including the medical sector. — Free specialized languages that provide extremely broad capabilities for solving both typical and non-standard tasks. The leader for solving statistical tasks in this category is the R environment: a powerful language for statistical analysis; in its basic form it requires working with the command line, although it is more commonly used with shells such as RStudio. In recent years, the Python language has also become widely used for such tasks. Python has a broader field of application than R: with Python one can solve tasks that R cannot handle, but in its "own" field (statistics) R remains the most powerful tool available. For certain categories of tasks, R remains the optimal instrument because the very structure of this language incorporates optimization for statistical computations. The use of sixth-category programs permits the greatest concentration on the substance of the problems being solved. Unfortunately, it is associated with the necessity of choosing between purchasing an expensive (often very expensive!) license or using cracked, pirated versions. However, StatSoft now provides the possibility of obtaining a license for educational use of its software product. An important advantage of paid professional specialized programs is that precisely such programs allow the fastest acquisition of experience working with data, including the use of multivariate analysis methods requiring complex computations. One of the authors of this textbook began working with the Statistica program from StatSoft (in its earlier incarnation) around 1992 (at that time it was called CSS, and it was designed for use in MS DOS). At that time, this was the program used by qualified zoologists in post-Soviet countries. The choice made then determined the program on which the exposition in this textbook was initially oriented. It must be admitted that it is extraordinarily difficult for a person accustomed to working in a program with a windowed interface, selecting options from a proposed list, to transition to working in command-line mode, which requires remembering the names and syntax of the necessary commands. However, the time of such programs has already passed. One must master the R environment... Of course, in recent years R has been experiencing increasingly intense competition from the more versatile Python programming language; nevertheless, for the time being, a specialist biologist cannot do without R. 3.2 The R Language The history of R began with the S language, developed by Bell Laboratories (Bell Labs) — an American company that played a key role in the development of software. This was a language designed for statistical computations (which explains the letter S), named by analogy with the C programming language.
In time, a version S+ also appeared. Both S and S+ were paid and sufficiently expensive products. In time, activists of the GNU project turned their attention to this language. The GNU project (GNU's Not UNIX) was started in 1983 by Richard Stallman. This American programmer left the university so that an operating system similar to Unix (a modular operating system based on ideas developed at Bell Labs) would not belong to any single organization. Stallman's initiative led to the emergence of the free software movement. In 1991, Linus Torvalds began work on the kernel of an operating system version that was named Linux. Both Linux and other products created under the GNU license are free software, one of the most remarkable achievements of human cooperation. Naturally, in time two GNU activists decided to create a free analogue of the S+ language within the framework of that project. Ross Ihaka and Robert Gentleman, faculty members of the Department of Statistics at the University of Auckland (in New Zealand), began work on this task in 1992. In 1993 the first experimental implementation of this free statistical programming language appeared. By analogy with S, this language was also given a single-letter name — the first letter of the names of its "parents". Over time the R community grew extraordinarily. R is a free and open product. It is a programming language for solving problems in the field of statistics and modeling, as well as an open-source environment for computing and graphics. R is distributed both as source code and as a compiled (translated from programming language into machine code) program. R is available under Linux (a "kindred" operating system, another result of the development of Bell Labs approaches in the GNU project), Windows, and macOS. On the whole, this language is the large-scale result of the altruistic activity of an enormous global community of intellectuals (with a special role played by representatives of the New Zealand statistical school). The center around which this community is organized is the site r-project.org. Over time, popular innovations spread through the R community. Thus, one can work with "bare" R, or use one or another shell. The most widespread shell for R is RStudio. The scientific director of RStudio, Professor of Statistics at the University of Auckland (and a biologist by first degree) Hadley Wickham has substantially influenced the development of the R language. He is, for instance, the author of the concept of tidy data (in reality a new name for a long-known organization of statistical data: observations in rows, characteristics in columns) and a number of popular packages that are part of the tidyverse suite. The most popular of these packages is ggplot2, which has in effect become one of the standards of scientific graphics. For our course, all three of the persons mentioned may be considered "founding fathers" (Fig. 3.2.1), since we will be using R through the RStudio shell and will apply components of the tidyverse suite. Fig. 3.2.1. "Gurus" of R: Ross Ihaka and Robert Gentleman (source), Hadley Wickham (source) R is a high-level, object-oriented, interpreted programming language. The high-level nature of this language is related to the fact that its constructs are oriented toward the human mind rather than toward a computer processor (though that mind must work logically, consistently, and unambiguously). The R language is object-oriented because it contains descriptions of individual objects that possess certain attributes. Objects can belong to two categories: data objects, designed for storing data, and function objects, which perform certain transformations of other objects. The object on which a function operated does not itself change; to retain the results of a function's operation, those results must be converted into a new object or, by a separate command, the old object must be replaced with a new one. To understand the advantage of R's interpreted nature, it should be noted that programming languages can be compiled or interpreted. Programs written in compiled languages are "translated" into the machine code that controls the processor as a single unit. Programs written in interpreted languages are converted into codes step by step, command by command. Because R is an interpreted language, a program written in R — a script (a chain of commands) — can be executed step by step or in part. This is very convenient for debugging such a program in cases where something does not work from the first attempt (that is, in the typical case). An R script can be modified at any point. To repeat a previously performed sequence of operations in R, it suffices to modify the script and run it again. It should be noted that typical work with R may consist of step-by-step overcoming of difficulties: something must be done; one searches for information, makes attempts, encounters failures, searches for their causes, overcomes them step by step, optimizes the script, corrects errors, reaches an impasse, finds a way out... and ultimately derives satisfaction from solving the problem. Like it or not, to use R one must overcome a certain entry threshold.
A typical situation is one in which a person with no prior R experience (and, even worse, who has experience working with programs organized in a fundamentally different way) attempts to solve some task in R. In the first steps, nothing will be comprehensible!
The playful approach that relies on intuitively understandable working logic does not work in a software environment that demands unambiguity.
Quite often this leads to disillusionment with R and a return to less sophisticated tools. On the other hand, when dealing with a specialist who uses this language, one can conclude that they know how to overcome obstacles and, when necessary, can manage their own frustration. ...one of the authors of this textbook undertook an internship at one of the world's best universities, studying under a specialist who had made great advances in the application of R. The internship concerned the use of R in simulation modeling rather than in statistics, but the lessons learned in the course of this training are fully applicable to our topic. The intern wished to make the most efficient use of the master's time. Several days before the substantive meeting, the intern attempted to solve the task independently and immediately encountered problems. Clearly, the necessary transformations could be performed, but how? Intuitively obvious paths led to program crashes and the appearance of strange messages... The intern did not want to spend time in joint work on what could be found on the internet. He searched Google for solutions to analogous problems, found analogies, tried to apply them, and failed repeatedly. In such a situation it is hard not to express oneself aloud; it is clear that neither R nor the authors of the advice that could not be applied are at fault, but swearing somehow relieves the feeling of failure... However, after spending several hours searching and making futile attempts, progress was eventually made one step at a time. By the time of the first joint session with the master, several such steps had been accomplished. Then came the moment when the intern explained what help he needed. "I have no idea how this should be done," said the guru: "We must search." The specialist turned to Google; it should be noted that he formulated queries in such a way that he obtained results more quickly. The first attempts to apply what was found were unsuccessful; the master received error messages from R and swore in response. Since both master and intern belonged to the same culture, the language they used upon failure was more or less similar... Nevertheless, the guru was able fairly quickly to take the necessary step, then another. The specialist's qualification was demonstrated not in knowing the answer to non-trivial questions in advance (nor even in swearing more effectively), but in the fact that through trial and error, using the collective wisdom of the internet, he advanced far more quickly than a novice. Ultimately, the model that was being created during that internship was completed. It immediately became apparent that it was not optimal; the script had to be revised. During experiments with the model it was discovered that one of the assumptions made during its construction was unsatisfactory; the model had to be rewritten... Dear students! If in the course of working with R you feel like fools, and R at some moment seems to be a means of tormenting you, do not worry: these are typical experiences. What matters is that they should not stop you. If your efforts continue, you will prevail, and thanks to the efforts expended, the feeling of your victory will be especially keen. 3.3 Brief Overview of R Commands The material of this section is based on the "cheat sheet" located on the official R project page, as well as its Russian-language version. 3.3.1 Help help(topic), ?topic — help on topic help.search("pattern"), ??pattern — global search for pattern help(package = ) — help on the specified package help.start() — launch help in browser apropos(what) — names of objects matching what args(name) — arguments of command name example(topic) — examples of usage for topic 3.3.2 Environment ls() — list all objects rm(x) — remove object dir() — show all files in the current directory getwd() — show current directory setwd(dir) — change current directory to dir 3.3.3 Object Inspection str(object) — internal structure of object summary(object) — general information about object dput(x) — obtain representation of object in R syntax head(x) — view initial rows of object tail(x) — view final rows of object 3.3.4 Input and Output library(package) — load package save(file, ...) — saves specified objects in platform-independent binary XDR format load() — loads data previously saved by the save() command read.table — reads a data table and creates a data.frame from it write.table — prints an object, converting it to a data.frame read.csv — reads a csv file read.delim — reads tab-delimited data save.image — saves all objects to a file cat(..., file= , sep= ) — saves arguments, concatenating them via sep sink(file) — redirects output of subsequent commands to a file in real time until this command is called without arguments 3.3.5 Creating Objects from:to — generates a sequence of numbers from from to to with step 1, e.g. 1:3 c(...) — combines arguments into a vector, e.g. c(1, 2, 3) seq(from, to, by = ) — generates a sequence of numbers from from to to with step by seq(from, to, len = ) — generates a sequence of numbers from from to to of length len rep(x, times) — repeats x times times list(...) — creates a list of objects data.frame(...) — creates a data frame array(data, dims) — creates a multidimensional array from data with dimensions dim matrix(data, nrow = , ncol = , byrow = ) — creates a nrow by ncol matrix from data; the fill order is determined by byrow factor(x, levels = ) — creates a factor from x with levels levels gl(n, k, length = n*k, labels = 1:n) — creates a factor of n levels, each repeated k times, of length length with names labels rbind(...) — combines arguments by rows cbind(...) — combines arguments by columns 3.3.6 Indexing Vectors x[n] — nth element x[-n] — all elements except the nth x[1:n] — first n elements x[-(1:n)] — all elements except the first n x[c(1,4,2)] — elements with the listed indices x["name"] — element with the specified name x[x > 3] — all elements greater than 3 x[x > 3 & x < 5] — all elements between 3 and 5 x[x %in% c("a","and","the")] — all elements from the specified set Lists x[n] — a list consisting of element n — nth element of the list — element of the list with name name x$name — element of the list with name name Matrices x[i, j] — element at the intersection of row i and column j x[i,] — row i x[,j] — column j x[,c(1,3)] — specified subset of columns x["name", ] — row with name name Data Frames — column with name name x$name — column with name name 3.3.7 Working with Variables as.array(x), as.data.frame(x), as.numeric(x), as.logical(x), as.complex(x), as.character(x) — convert object to a specified type is.na(x), is.null(x), is.array(x), is.data.frame(x), is.numeric(x), is.complex(x), is.character(x) — check whether the object belongs to a specified type length(x) — number of elements in x dim(x) — dimensions of object x dimnames(x) — names of dimensions of object x names(x) — names of object x nrow(x) — number of rows of x ncol(x) — number of columns of x class(x) — class of object x unclass(x) — extracts the class attribute of object x attr(x,which) — attribute which of object x attributes(obj) — list of attributes of object obj 3.3.8 Data Management which.max(x) — index of the element with the maximum value which.min(x) — index of the element with the minimum value rev(x) — reverses the order of elements sort(x) — sorts elements of the object in ascending order cut(x,breaks) — divides the vector into equal intervals match(x, y) — finds elements of x that are present in y which(x == a) — returns the positional indices of x that equal a na.omit(x) — excludes missing values (NA) from the object (in a matrix or data frame, excludes the corresponding row) na.fail(x) — returns an error message if the object contains NA unique(x) — removes duplicate elements from the object table(x) — creates a table with the count of each unique element subset(x, ...) — returns the subset of elements of the object satisfying the specified condition sample(x, size) — returns a random sample of size size from elements of x replace(x, list, values) — replaces values in x at indices from list with the values values append(x, values) — appends elements values to vector x 3.3.9 Mathematics sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y, x), log(x), log(x, base), log10(x), exp(x) — elementary mathematical functions min(x), max(x) — minimum and maximum elements of the object range(x) — vector of the minimum and maximum elements of the object pmin(x, y), pmax(x, y) — returns a vector of minimum (maximum) values for each pair x[i], y[i] sum(x) — sum of elements of the object prod(x) — product (result of multiplication) of elements of the object diff(x) — returns a vector of differences between adjacent elements mean(x) — arithmetic mean of elements of the object median(x) — median of the object weighted.mean(x, w) — weighted mean of object x (w specifies the weights) round(x, n) — rounds x to n decimal places cumsum(x), cumprod(x), cummin(x), cummax(x) — cumulative sums, products, minima, and maxima of vector x (the ith element contains the statistic for elements x[1:i]) union(x, y), intersect(x, y), setdiff(x,y), setequal(x,y), is.element(el,set) — set operations: union, intersection, difference, membership Re(x), Im(x), Mod(x), Arg(x), Conj(x) — operations on complex numbers: real part, imaginary part, modulus, argument, conjugate fft(x), mvfft(x) — fast Fourier transform choose(n, k) — number of combinations rank(x) — ranks the elements of the object 3.3.10 Matrices %*% — matrix multiplication t(x) — transposed matrix diag(x) — diagonal of the matrix solve(a, b) — solves the system of equations a %*% x = b solve(a) — inverse matrix colSums, rowSums, colMeans, rowMeans — sums and means by columns and rows 3.3.11 Data Reshaping apply(X,INDEX,FUN =) — returns a vector, array, or list of values obtained by applying function FUN to certain elements of array or matrix x; the elements to be processed are specified by the MARGIN argument lapply(X,FUN) — returns a list of the same length as x; the values in the new list are the result of applying function FUN to the elements of the original object x tapply(X,INDEX,FUN =) — applies function FUN to each set of values of x formed according to the levels of a specified factor; the list of factors is specified by the INDEX argument by(data,INDEX,FUN) — analogue of tapply(), applied to data tables merge(a,b) — merges two data tables (a and b) by common columns or rows aggregate(x,by,FUN) — splits data table x into separate data sets, applies a specified function FUN to these sets, and returns the result in a readable format stack(x, ...) — converts data represented in object x as separate columns into a data table unstack(x, ...) — performs the operation inverse to stack() reshape(x, ...) — converts a data table from "wide format" (repeated measurements of any value recorded in separate columns of the table) into "long format" (repeated measurements appear one below another within a single column) Date and Time as.Date(s) — converts vector s to an object of class Date as.POSIXct(s) — converts vector s to an object of class POSIXct 3.3.12 Strings print(x) — prints x to the screen sprintf(fmt, ...) — text formatting in C style (can use %s, %.5f, etc.) format(x) — formats object x so that it appears well-formatted when printed to the screen paste(...) — converts vectors to character variables and concatenates them into a single string substr(x,start,stop) — extracts a substring strsplit(x,split) — splits string x into substrings according to split grep(pattern,x) (as well as grepl, regexpr, gregexpr, regexec) — search by regular expression gsub(pattern,replacement,x) (as well as sub) — replacement by regular expression tolower(x) — convert string to lower case toupper(x) — convert string to upper case match(x,table), x %in% table — searches for elements in vector table that match values from vector x pmatch(x,table) — searches for elements in vector table that partially match values from vector x nchar(x) — returns the number of characters in string x 3.3.13 Plots plot(x) — plot of x plot(x, y) — plot of y as a function of x hist(x) — histogram barplot(x) — bar chart dotchart(x) — Cleveland dot chart pie(x) — pie chart boxplot(x) — box-and-whisker plot sunflowerplot(x, y) — same as plot(), but points with identical coordinates are displayed as "sunflowers" whose number of petals is proportional to the number of such points coplot(x~y | z) — plot of y as a function of x for each interval of values of z interaction.plot(f1, f2, y) — if f1 and f2 are factors, this function creates a plot with mean values according to values of f1 (on the x-axis) and f2 (on the y-axis, different curves) matplot(x, y) — plot of columns of y against columns of x fourfoldplot(x) — displays (as portions of a circle) the association between two binary variables in different populations assocplot(x) — Cohen-Friendly association plot mosaicplot(x) — mosaic plot of residuals from log-linear regression pairs(x) — if x is a matrix or data frame, this function plots scatter diagrams for all possible pairs of variables from x plot.ts(x), ts.plot(x) — plots a time series qqnorm(x) — quantile-quantile plot against normal distribution qqplot(x, y) — plot of quantiles of y against quantiles of x contour(x, y, z) — interpolates data and creates a contour plot filled.contour(x, y, z) — same as contour(), but fills areas between contours with colors image(x, y, z) — displays data as squares whose color is determined by the values of x and y persp(x, y, z) — same as image(), but as a three-dimensional plot stars(x) — if x is a matrix or data frame, displays a plot as "stars" such that each row is represented by a "star" and columns determine the lengths of the rays of those "stars" symbols(x, y, ...) — displays various symbols according to coordinates termplot(mod.obj) — displays partial effects of variables from a regression model 3.3.14 Individual Plot Elements points(x, y) — drawing points lines(x, y) — drawing a line text(x, y, labels, ...) — adding a text label mtext(text, side=3, line=0, ...) — adding a text label segments(x0, y0, x1, y1) — adding a line segment arrows(x0, y0, x1, y1, angle= 30, code=2) — drawing an arrow abline(a,b) — drawing a slanted line abline(h=y) — drawing a horizontal line abline(v=x) — drawing a vertical line abline(lm.obj) — drawing a regression line rect(x1, y1, x2, y2) — drawing a rectangle polygon(x, y) — drawing a polygon legend(x, y, legend) — adding a legend title() — adding a title axis(side, vect) — adding axes rug(x) — drawing tick marks on the X axis locator(n, type = "n", ...) — returns coordinates on the plot in response to a user click 3.3.15 Lattice Plots xyplot(y~x) — plot of y as a function of x barchart(y~x) — bar chart dotplot(y~x) — Cleveland dot chart densityplot(~x) — density plot of the distribution of values of x histogram(~x) — histogram of values of x bwplot(y~x) — box-and-whisker plot qqmath(~x) — analogue of the qqnorm() function stripplot(y~x) — analogue of the stripplot(x) function qq(y~x) — displays quantiles of the distributions of x and y for visual comparison of these distributions; variable x must be numeric, variable y must be numeric, character, or a factor with two levels splom(~x) — scatter plot matrix (analogue of the pairs() function) levelplot(z~xy|g1g2) — color plot of values of z whose coordinates are given by variables x and y (clearly x, y, and z must have the same length); g1, g2 ... (if present) are factors or numeric variables whose values are automatically divided into equal intervals wireframe(z~xy|g1g2) — function for constructing three-dimensional scatter plots and surfaces; z, x, and y are numeric vectors; g1, g2 ... (if present) are factors or numeric variables whose values are automatically divided into equal intervals cloud(z~xy|g1g2) — three-dimensional scatter plot 3.3.16 Optimization and Parameter Fitting optim(par, fn, method = ) — general-purpose optimization nlm(f,p) — minimization of function f by Newton's algorithm lm(formula) — fitting a linear model glm(formula,family=) — fitting a generalized linear model nls(formula) — nonlinear least squares approx(x,y=) — linear interpolation spline(x,y=) — cubic spline interpolation loess(formula) — fitting a polynomial surface predict(fit,...) — constructing predictions coef(fit) — estimated coefficients 3.3.17 Statistics sd(x) — standard deviation var(x) — variance cor(x) — correlation matrix var(x, y) — covariance between x and y cor(x, y) — linear correlation between x and y aov(formula) — analysis of variance anova(fit,...) — analysis of variance for fitted models fit density(x) — kernel probability densities binom.test() — exact test of a simple hypothesis about the probability of success in Bernoulli trials pairwise.t.test() — pairwise comparisons of several independent or dependent samples prop.test() — test of the hypothesis of equal frequencies of a given characteristic across all groups analyzed t.test() — Student's t-test 3.3.18 Distributions rnorm(n, mean=0, sd=1) — normal distribution rexp(n, rate=1) — exponential distribution rgamma(n, shape, scale=1) — gamma distribution rpois(n, lambda) — Poisson distribution rweibull(n, shape, scale=1) — Weibull distribution rcauchy(n, location=0, scale=1) — Cauchy distribution rbeta(n, shape1, shape2) — beta distribution rt(n, df) — Student's t-distribution rf(n, df1, df2) — Fisher's F-distribution rchisq(n, df) — Pearson's chi-squared distribution rbinom(n, size, prob) — binomial distribution rgeom(n, prob) — geometric distribution rhyper(nn, m, n, k) — hypergeometric distribution rlogis(n, location=0, scale=1) — logistic distribution rlnorm(n, meanlog=0, sdlog=1) — log-normal distribution rnbinom(n, size, prob) — negative binomial distribution runif(n, min=0, max=1) — uniform distribution 3.3.19 Programming Working with Functions function(arglist) { expr } — creates a user-defined function return(value) — returns a value do.call(funname, args) — calls a function by name Conditional Operators if(cond) expr if(cond) cons.expr else alt.expr ifelse(test, yes, no) Loops for(var in seq) expr while(cond) expr repeat expr break — stops the loop 3.4 R: Useful References Several books can be used to master R. In Ukrainian, the following publication is recommended: Maiboroda R. Ye. Kompiuterna statystyka. Kyiv: VPTs "Kyivskyi universytet", 2019. – 589 p. The number of English-language books devoted to R is enormous. The following outstanding books are freely available on the internet: 1. Advanced R: https://adv-r.hadley.nz/ 2. R for Data Science: https://r4ds.had.co.nz/ 3. R Packages: https://r-pkgs.org/ 4. R Graphics Cookbook: https://r-graphics.org/ 5. Modern Data Visualization with R: https://rkabacoff.github.io/datavis/ The first of these books is available in Russian translation: Wickham H., Grolemund G., Çetinkaya-Rundel M. R. K vershinam masterstva. Moscow: DMK Press, 2024. – 752 p. An earlier edition of the second of these books is also available in Russian translation: Wickham H., Grolemund G. Yazyk R v zadachakh nauki o dannykh. Import, podgotovka, obrabotka, vizualizatsiya i modelirovanie dannykh. Saint Petersburg: OOO "Dialektika", 2018. – 592 p. Another useful book: Field A., Miles J. and Field Z. Discovering Statistics using R. SAGE Publications, 2012. – 957 p. Is there value in using Russian-language sources under conditions in which Muscovy is waging war against our country? We believe that in cases of insufficient command of English, and given the shortage of Ukrainian technical literature, the technical use of Russian-language and Russia-published literature may be beneficial. However, whenever possible, English-language sources should be used and Ukrainian ones should be created. The prospects of the Russian language, under conditions in which the Russian state has become an enormous threat to the entire planet, are bleak. Well, this is not our fault. The German language, which was one of the universally recognized international languages of science prior to World War II, substantially lost its international standing as a result of the actions of Hitler's government. Even modern Germany's active condemnation of its Nazi past has not fully reversed these losses. When this course is being written, Muscovy's condemnation of Russian imperialism and Putinism is still far off; a large portion of Russian scientists support, to one degree or another, the imperial sentiments of their country. Nevertheless, despite the unfavorable prognosis for Russian-language science and culture, we consider the limited use of Russian sources to be a temporarily permissible measure. The first six Russian-language books listed below are translations from English; their original versions are also available on the internet. Kabakov R.I. R v deistvii. Analiz i vizualizatsiya dannykh s ispolzovaniem R i Tidyverse. Moscow: DMK Press, 2023. – 768 p. The earlier edition of this book contains advice on the use of base R that may also prove useful: Kabakov R.I. R v deistvii. Analiz i vizualizatsiya dannykh v programme R. Moscow: DMK Press, 2014. – 588 p. Long J.D., Teetor P. R. Kniga retseptov. Proverennye retsepty dlya statistiki, analiza i vizualizatsii. Moscow: DMK Press, 2020. – 510 p. Matloff N. Iskusstvo programmirovaniya na R. Pogruzhenie v bolshie dannye. Saint Petersburg: Piter, 2019. – 416 p. James G., Witten D., Hastie T., Tibshirani R. Vvedenie v statisticheskoe obuchenie s primerami na yazyke R. Moscow: DMK Press, 2017. – 456 p. Bruce P., Bruce A. Prakticheskaya statistika dlya spetsialistov Data Science. Saint Petersburg: BKhV-Peterburg, 2018. – 304 p. Wilke C. Osnovy vizualizatsii dannykh: posobie po effektivnoi i ubeditel'noi podache informatsii. Moscow: Eksmo, 2024. – 352 p. Mastitsky S.E., Shitikov V.K. Statisticheskiy analiz i vizualizatsiya dannykh s pomoshchyu R. Moscow: DMK Press, 2015. – 496 p. Mastitsky S.E. Vizualizatsiya dannykh s pomoshchyu ggplot2. Moscow: DMK Press, 2017. – 222 p. Shipunov A.B., Baldin E.M., Volkova P.A. et al. Naglyadnaya statistika. Ispolzuem R! Moscow: DMK Press, 2014. – 298 p. In addition to the books listed, the following materials may be useful: R Programming Tutorial Samsonov T. Vizualizatsiya i analiz geograficheskikh dannykh na yazyke R. Online course. Herve M. Putevoditel po primeneniyu statisticheskikh metodov s ispolzovaniem R Vvedenie v R — sistemu statisticheskogo analiza dannykh (Obzor R-sredstv dlya resheniya izbrannykh problem) Schematic: Data Visualization with ggplot2 Mastitsky S. Rabota s RStudio On the internet there are blogs devoted to R, including r-analytics and statinr, as well as very clearly written reviews here. Interesting instructional materials (conveniently organized in a concise format) can be found here. Some non-trivial topics are addressed in this training course. In general, searches on YouTube and in Google can yield much of interest. It should be noted that the authors have provided links here to electronic versions of several books not for profit, but in support of students' learning (and their own efforts to master R). Some of these books are offered for distribution by their authors (such as, for example, the textbook by R. Ye. Maiboroda). 3.5 R Wizard of ChatGPT: An Aid for the Diligent, a Trap for the Lazy In recent years one can observe the rapid development of AI tools. Over the period during which the authors of this textbook have been working with R, the capabilities that ChatGPT provides for working with R have expanded considerably. This is connected above all with the appearance of a specialized tool: R Wizard.