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
Multiple Boxplots Using Ggplot
Display Y-Axis for Each Subplot When Faceting
Icu Init Failed: U_File_Access_Error - When Running Swirl
Replace Na with Groups Mean in a Non Specified Number of Columns
Get All the Rows with Rownames Starting with Abc111
Using Rcpp Functions Inside of R's Par*Apply Functions from the Parallel Package
Loop Character Values in Ggtitle
Subtracting Values Group-Wise by the Average of Each Group in R
Remove Strings Found in Vector 1, from Vector 2
R How to Convert a Numeric into Factor with Predefined Labels
Shiny Dynamic Filter Variable Selection and Display of Variable Values for Selection
Create Unique Identifier from the Interchangeable Combination of Two Variables
How to Extract All the Rows If a Level in One Column Contains All the Levels of Another Column in R
Plot Causes "Error: Incorrect Number of Dimensions"
Link Selectinput with Sliderinput in Shiny
Selection of Activity Trace in a Chart and Display in a Data Table in R Shiny