Return a Matrix with 'Ifelse'

Return a matrix with `ifelse`

The length of the return is completely decided by length(a == 1). See also the helpfile with ?ifelse. Your code will only return a single value.

ifelse targets vector input / output. Even if you get the length correct, say: ifelse(rep(TRUE, 6), mat, mat2), you get a vector rather than a matrix output. So an outer matrix call to reset dimension is necessary.


Tip 1:

For your example, looks like a simple result <- if (a == 1) mat else mat2 is sufficient. No need to touch ifelse.

Tip 2:

It is not impossible to ask ifelse to return a matrix, but you have to protect it by a list (remember a list is a vector):

ifelse(TRUE, list(mat), list(mat2))

But, this is inconvenient.

ifelse statement returning a conditional matrix element in R

You can actually use a matrix of row and column names or indices to subset a matrix.

With this notation, your problem is a one-liner:

data$movement = ax[as.matrix(data)]

data
# Location1 Location2 movement
# 1 site1 site1 x
# 2 site1 site2 DN
# 3 site2 site1 UP
# 4 site1 site2 DN
# 5 site2 site2 x
# 6 site2 site2 x
# 7 site2 site1 UP
# 8 site1 site1 x

Your ifelse isn't working because ifelse wants the test, the yes result, and the no result to all be vectors of the same length. Your yes result, however, is this:

ax[as.character(data$Location1),as.character(data$Location2)]
# site1 site2 site1 site2 site2 site2 site1 site1
# site1 "x" "DN" "x" "DN" "DN" "DN" "x" "x"
# site1 "x" "DN" "x" "DN" "DN" "DN" "x" "x"
# site2 "UP" "x" "UP" "x" "x" "x" "UP" "UP"
# site1 "x" "DN" "x" "DN" "DN" "DN" "x" "x"
# site2 "UP" "x" "UP" "x" "x" "x" "UP" "UP"
# site2 "UP" "x" "UP" "x" "x" "x" "UP" "UP"
# site2 "UP" "x" "UP" "x" "x" "x" "UP" "UP"
# site1 "x" "DN" "x" "DN" "DN" "DN" "x" "x"

which is easily coerced to a vector, but then it is the wrong length. The diagonal of this matrix is your desired result, so you could use diag(ax[as.character(data$Location1),as.character(data$Location2)]) in the ifelse, or you could even use

data$movement = diag(ax[as.character(data$Location1), as.character(data$Location2)])

but the above way is even better.

Ifelse for matrix in R

Try this, using a much smaller example set (and a seed for reproducibility):

cenarios = 5
tamanho = 6
sev_med = 6
replicacoes_ind = matrix(NA, tamanho, cenarios)
replicacoes_sev = matrix(NA, tamanho, cenarios)
SAg = array(NA, cenarios)
quant_sin = array(NA, cenarios)

set.seed(42)
u = matrix(data=runif(tamanho*cenarios, 0, 1), nrow=tamanho, ncol=cenarios)
u
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0.9148060 0.7365883 0.9346722 0.4749971 0.08243756
# [2,] 0.9370754 0.1346666 0.2554288 0.5603327 0.51421178
# [3,] 0.2861395 0.6569923 0.4622928 0.9040314 0.39020347
# [4,] 0.8304476 0.7050648 0.9400145 0.1387102 0.90573813
# [5,] 0.6417455 0.4577418 0.9782264 0.9888917 0.44696963
# [6,] 0.5190959 0.7191123 0.1174874 0.9466682 0.83600426

For grins, I'll set a limit of 0.15 so that we can replace a few of the values:

prob_sin <- 0.15
ind <- (u <= prob_sin)
ind
# [,1] [,2] [,3] [,4] [,5]
# [1,] FALSE FALSE FALSE FALSE TRUE
# [2,] FALSE TRUE FALSE FALSE FALSE
# [3,] FALSE FALSE FALSE FALSE FALSE
# [4,] FALSE FALSE FALSE TRUE FALSE
# [5,] FALSE FALSE FALSE FALSE FALSE
# [6,] FALSE FALSE TRUE FALSE FALSE

From here, we can generate the 0s and 1s in one step:

replicacoes_ind <- +ind
replicacoes_ind
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0 0 0 0 1
# [2,] 0 1 0 0 0
# [3,] 0 0 0 0 0
# [4,] 0 0 0 1 0
# [5,] 0 0 0 0 0
# [6,] 0 0 1 0 0

The second matrix is about the same:

replicacoes_sev[ind] <- rexp(sum(ind), rate = 1/sev_med)
replicacoes_sev
# [,1] [,2] [,3] [,4] [,5]
# [1,] NA NA NA NA 41.07943
# [2,] NA 25.00878 NA NA NA
# [3,] NA NA NA NA NA
# [4,] NA NA NA 0.1728925 NA
# [5,] NA NA NA NA NA
# [6,] NA NA 7.170642 NA NA
replicacoes_sev[!ind] <- 0
replicacoes_sev
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0 0.00000 0.000000 0.0000000 41.07943
# [2,] 0 25.00878 0.000000 0.0000000 0.00000
# [3,] 0 0.00000 0.000000 0.0000000 0.00000
# [4,] 0 0.00000 0.000000 0.1728925 0.00000
# [5,] 0 0.00000 0.000000 0.0000000 0.00000
# [6,] 0 0.00000 7.170642 0.0000000 0.00000

How to change matrix entries using conditional if in R

You do not need loops here. Just use the whole matrix in your call to x>5

ifelse(MAT>5, "YES", "NO")

This will do the logical operation over the entire matrix, and output a logical matrix.

You can reassign the VALUES from the output of ifelse() while keeping the STRUCTURE of MAT by using the empty brackets [], as in:

MAT[]<-ifelse(MAT>5, "YES", "NO")

Use ifelse to extract information from a matrix

We could use outer with max.col

m1 <- t(outer( g[,1] + g[,2], m,  `==`)* g[,3])
max.col(m1) * (rowSums(m1!= 0) !=0)
#[1] 1 4 7 11 17 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

ifelse function in R

In my opinion it is because of the dim of your logical input. Ifelse returns a value of the same dim as your logical input.

Try this:

c(fde.4$ResourceId ,fde.4$FullYearForecast, is.na(fde.2$8))==c(2196,'Yes', FALSE)


Related Topics



Leave a reply



Submit