plot coordinates from two vectors into a 0,1 matrix - r

I have two vectors of equal length
a <- 1:10
b <- sample.int(10,size=10)
I would like to plot them into a matrix of the same length (10) where a is the row coordinate, b the column coordinate, with the value 1 for the coordinates and 0 for everything else. I have below a way to do this using a for loop, but was hoping to do this without a loop. Thanks!
matrix01 <- matrix(0, nrow = 10, ncol = 10)
for(i in 1:10) {
matrix01[i, b[i]] = 1
}

1) Use replace and cbind like this:
replace(matrix(0, 10, 10), cbind(a, b), 1)
2) In the question a equals 1:10 and in that special case (but not more generally) another possibility is:
+ outer(b, 1:10, `==`)
or
+ sapply(1:10, `==`, b)
3) In the question a is 1:10 and b is a premutation of 1:10. In that special case (but not more generally) this works:
diag(10)[b, ]
4) In the question both a and b are premutations of 1:10 and in that special case (but not more generally) this works to give a table:
table(a, b)
This would also work and is similar:
xtabs(~ a + b)
Note
Note that the question
uses seq(1:10) which should be just 1:10
needs to add set.seed to make the input reproducible
defines a but then does not use it in the code

You can create a row/column matrix using cbind and assign the value 1 to those position.
matrix01[cbind(a, b)] <- 1

Related

even and odd number in matrix

I want to write a code for a matrix and return the number of odd and even with using function.
for example, I run this code for odd and even but I don't know how to determine the number of even and odd in the matrix.
x = 1:9
u = matrix(x, 3, 3)
fu = function(u){
if(u%%2 ==0)(return("joz"))
else{
return("fard")
}
}
fu(3)
[1] "fard"
If you are looking to get counts of how many are odd/even
odd_even <- function(x) c("odd"=sum(x%%2), "even"=sum(!x%%2))
E.g. this gives 3 and 6
x <- matrix(c(1,3,5,1,7,9,8,8,2), nrow=3)
odd_even(x)
Here is a base R one-line solution.
even_odd <- function(x) setNames(table(x %% 2), c("even", "odd"))
a <- matrix(1:9, 3)
even_odd(a)
#even odd
# 4 5

How to find out the best combination of a given vector whose sum is closest to a given number

My question is quite similar to this one: Find a subset from a set of integer whose sum is closest to a value
It discussed the algorithm only, but I want to solve it with R. I'm quite new to R and tried to work out a solution, but I wonder whether there is a more efficient way.
Here is my example:
# Define a vector, to findout a subset whose sum is closest to the reference number 20.
A <- c(2,5,6,3,7)
# display all the possible combinations
y1 <- combn(A,1)
y2 <- combn(A,2)
y3 <- combn(A,3)
y4 <- combn(A,4)
y5 <- combn(A,5)
Y <- list(y1,y2,y3,y4,y5)
# calculate the distance to the reference number of each combination
s1 <- abs(apply(y1,2,sum)-20)
s2 <- abs(apply(y2,2,sum)-20)
s3 <- abs(apply(y3,2,sum)-20)
s4 <- abs(apply(y4,2,sum)-20)
s5 <- abs(apply(y5,2,sum)-20)
S <- list(s1,s2,s3,s4,s5)
# find the minimum difference
M <- sapply(S,FUN=function(x) list(which.min(x),min(x)))
Mm <- which.min(as.numeric(M[2,]))
# return the right combination
data.frame(Y[Mm])[as.numeric(M[,Mm[1]])]
so the answer is 2,5,6,7.
How can I refine this program? Especially the five combn()s and five apply()s, is there a way that can work them at once? I hope when A has more items in it, I can use length(A) to cover it.
Here is another way to do it,
l1 <- sapply(seq_along(A), function(i) combn(A, i))
l2 <- sapply(l1, function(i) abs(colSums(i) - 20))
Filter(length, Map(function(x, y)x[,y], l1, sapply(l2, function(i) i == Reduce(min, l2))))
#[[1]]
#[1] 2 5 6 7
The last line uses Map to index l1 based on a logical list created by finding the minimum value from list l2.
combiter library has isubsetv iterator, which goes through all subset of a vector. Combined with foreach simplifies the code.
library(combiter)
library(foreach)
A <- c(2,5,6,3,7)
res <- foreach(x = isubsetv(A), .combine = c) %do% sum(x)
absdif <- abs(res-20)
ind <- which(absdif==min(absdif))
as.list(isubsetv(A))[ind]

how to keep dimensions with alply and mapply

I have got a three dimensional array outmv. I dissolve its third dimension with the help of alply, because I want a list of two dimensional matrices, whose numbers of columns will depend on v (see mapply) and whose number of rows is given by r.
I have got two problems:
1. can I keep alply from dropping the r-dimension (if r = 1)? (although my workaround with the help of matrix() seems to work)
2. if vend = 5, mapply degenerates my desired output: in case fun(1,5) the result is transposed, in case fun(2,5) the result is even mixed. I really would like to have length(v) matrices, each of having got r rows, for further steps.
library(plyr)
fun <- function(r,vend){
m <- matrix(c(1:20),nrow = r, byrow = TRUE)
v <- c(5:vend)
outmv <- outer(m,v) # dim(outmv) = c(dim(m),length(v))
#outmv_dropped_dim <- alply(outmv,3,function(x) x)
#if r = 1, unfortunately, alply drops a dimension automatically,
#therefore, I cannot use function(x) = x, but
outmv_kept_dim <- alply(outmv,3,function(x) matrix(x,nrow = r,
ncol = ncol(m)))
mapply(function(x,y) {x[,c(1:y), drop = FALSE]},
x = outmv_kept_dim,
y = v)
}
#11 > vend > 5 works as desired
fun(2,6) #list elements have desired dimension
fun(1,6) #list elements have desired dimension
#v_end = 5 does not work as desired
fun(1,5) #result is transposed
fun(2,5) #result is transposed and mixed and therefore worse

Multiply unique pairs of values in a vector and sum the result

I want to multiply and then sum the unique pairs of a vector, excluding pairs made of the same element, such that for c(1:4):
(1*2) + (1*3) + (1*4) + (2*3) + (2*4) + (3*4) == 35
The following code works for the example above:
x <- c(1:4)
bar <- NULL
for( i in 1:length(x)) { bar <- c( bar, i * c((i+1) : length(x)))}
sum(bar[ 1 : (length(bar) - 2)])
However, my actual data is a vector of rational numbers, not integers, so the (i+1) portion of the loop will not work. Is there a way to look at the next element of the set after i, e.g. j, so that I could write i * c((j : length(x))?
I understand that for loops are usually not the most efficient approach, but I could not think of how to accomplish this via apply etc. Examples of that would be welcome, too. Thanks for your help.
An alternative to a loop would be to use combn and multiply the combinations using the FUN argument. Then sum the result:
sum(combn(x = 1:4, m = 2, FUN = function(x) x[1] * x[2]))
# [1] 35
Even better to use prod in FUN, as suggested by #bgoldst:
sum(combn(x = 1:4, m = 2, FUN = prod))

making an integer vector from index of another vector in R

I have just started to learn R, and trying to do the following task.
I have a vector of 10 random values few are NAs and few are numeric values in it, like
a <- rnorm(100)
b <- rep(NA, 100)
c <- sample(c(a, b), 10)
now I want to make another vector "d" which has indices of all the NA values in "c" for example
d <- c(2, 7, 9)
I tried
d <- which(c %in% is.na(c))
but its not giving me desired result
also what is wrong with this code i tried for the above purpose
navects <- function(x) {
for(i in 1:length(x)) {
if(is.na(x[i])) c(i)
}
}
You can try with which
which(is.na(c))
NOTE: c is also a function, so it is better not to name objects with c.

Resources