## [1] 25
## [1] 144
## [1] 169
## [1] 13
## [1] 13
## [1] 13
In the first code snippet, the variable i took on the values 1, 5, 9, and 13 as the loop went through its iterations. In that last case, the condition i <= 10 failed, so the break took hold and we left the loop.
This code shows three different ways of accomplishing the same thing, with break playing a key role in the second and third ways. Note that repeat has no Boolean exit condition. You must use break (or something like return()). Of course, break can be used with for loops, too.
R does not directly support iteration over nonvector sets, but there are a couple of indirect yet easy ways to accomplish it:
Let’s look at an example of using get(). Say we have two matrices, u and v, containing statistical data, and we wish to apply R’s linear regression function lm() to each of them.
u<-matrix(c(1,2,3,1,2,4), nrow=3)
v<-matrix(c(8,12,20,15,10,2), nrow=3)
for (m in c("u","v")) {
z <- get(m)
print(lm(z[,2] ~ z[,1]))
}##
## Call:
## lm(formula = z[, 2] ~ z[, 1])
##
## Coefficients:
## (Intercept) z[, 1]
## -0.6667 1.5000
##
##
## Call:
## lm(formula = z[, 2] ~ z[, 1])
##
## Coefficients:
## (Intercept) z[, 1]
## 23.286 -1.071
##
## Call:
## lm(formula = z[, 2] ~ z[, 1])
##
## Coefficients:
## (Intercept) z[, 1]
## 23.286 -1.071
The syntax for if-else looks like this:
## [1] 2
## [1] 4
Without taking this tack, the code
would instead consist of the somewhat more cluttered
Figure1
## [1] TRUE FALSE FALSE
## [1] TRUE
## [1] TRUE
## [1] "both TRUE"
## [1] "both TRUE"
The central point is that in evaluating an if, we need a single Boolean, not a vector of Booleans, hence the warning seen in the preceding example, as well as the need for having both the & and && operators.
The Boolean values TRUE and FALSE can be abbreviated as T and F (both must be capitalized). These values change to 1 and 0 in arithmetic expressions:
## [1] TRUE
## [1] 1
## [1] 0
## [1] TRUE
## [1] TRUE
In the second computation, for instance, the comparison 1 < 2 returns TRUE, and 3 < 4 yields TRUE as well. Both values are treated as 1 values, so the product is 1.
On the surface, R functions look similar to those of C, Java, and so on. However, they have much more of a functional programming flavor, which has direct implications for the R programmer.
In the previous lessons, we read in a data set from a file named exams:
read.table
function (file, header = FALSE, sep = "", quote = "\"'", dec = ".", row.names, col.names, as.is = !stringsAsFactors, na.strings = "NA", colClasses = NA, nrows = -1, skip = 0, check.names = TRUE, fill = !blank.lines.skip, strip.white = FALSE, blank.lines.skip = TRUE, comment.char = "#", allowEscapes = FALSE, flush = FALSE, stringsAsFactors = default.stringsAsFactors(), encoding = "unknown")
{
if (is.character(file)) {
file <- file(file, "r")
on.exit(close(file))
...
...oddcount<-function(x) {
k <- 0 # assign 0 to k
for (n in x) {
if (n %% 2 == 1) k <- k+1 # %% is the modulo operator
}
return(k)
}## $x
## {
## return(x + 1)
## }
## function(x) {
## return(x+1)
## }
## function (a = NULL, b = NULL, h = NULL, v = NULL, reg = NULL,
## coef = NULL, untf = FALSE, ...)
## {
## int_abline <- function(a, b, h, v, untf, col = par("col"),
## lty = par("lty"), lwd = par("lwd"), ...) .External.graphics(C_abline,
## a, b, h, v, untf, col, lty, lwd, ...)
## if (!is.null(reg)) {
## if (!is.null(a))
## warning("'a' is overridden by 'reg'")
## a <- reg
## }
## if (is.object(a) || is.list(a)) {
## p <- length(coefa <- as.vector(coef(a)))
## if (p > 2)
## warning(gettextf("only using the first two of %d regression coefficients",
## p), domain = NA)
## islm <- inherits(a, "lm")
## noInt <- if (islm)
## !as.logical(attr(stats::terms(a), "intercept"))
## else p == 1
## if (noInt) {
## a <- 0
## b <- coefa[1L]
## }
## else {
## a <- coefa[1L]
## b <- if (p >= 2)
## coefa[2L]
## else 0
## }
## }
## if (!is.null(coef)) {
## if (!is.null(a))
## warning("'a' and 'b' are overridden by 'coef'")
## a <- coef[1L]
## b <- coef[2L]
## }
## int_abline(a = a, b = b, h = h, v = v, untf = untf, ...)
## invisible()
## }
## <bytecode: 0x00000000150c0fc8>
## <environment: namespace:graphics>
An alternative is to edit it using the edit() function, which we will discuss in the next lecture.
Note, though, that some of R’s most fundamental built-in functions are written directly in C, and thus they are not viewable in this manner. Here’s an example:
## function (..., na.rm = FALSE) .Primitive("sum")
## [1] 5
## [1] 1
## [1] 5
## [1] 1
g1 <- function(x) return(sin(x))
g2 <- function(x) return(sqrt(x^2+1))
g3 <- function(x) return(2*x-1)
plot(c(0,1),c(-1,1.5)) # prepare the graph, specifying X and Y ranges
for (f in c(g1,g2,g3)) plot(f,0,1,add=T) # add plot to existing graph## function (h, a, b)
## 2 * x + 3
## [1] 5 3 5