I click on a excel macro button which uses RExcel to execute an R script that generates a matrix
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 0 0 -3 -3 -3 -3 -2
[2,] 0 0 0 0 4 4 4
[3,] 0 0 0 1 2 1 2
[4,] 0 0 0 0 0 0 1
[5,] 0 0 0 0 1 1 1
[6,] 0 0 0 0 1 1 1
[7,] 0 0 0 0 0 0 0
[8,] 0 0 0 0 0 0 0
[9,] 0 0 0 0 0 0 0
[10,] 0 0 0 0 0 0 1
[11,] 0 0 0 0 0 0 1
[12,] 0 1 1 1 1 1 1
[13,] 0 0 0 0 0 0 0
[14,] 0 0 0 0 0 0 0
[15,] 0 0 0 0 0 0 0
[16,] 0 -1 3 3 3 4 3
[17,] 0 1 2 2 2 1 0
[18,] 0 0 0 0 0 0 0
[19,] 0 -1 -2 -2 -2 -1 -1
[20,] 0 -2 -2 -3 -3 -5 -4
[21,] 0 0 0 0 0 0 0
[22,] 0 0 0 0 0 0 0
[23,] 0 1 1 1 1 1 1
[24,] 0 0 1 1 1 0 1
[25,] 0 0 1 1 1 0 1
[26,] 0 0 1 1 1 1 2
[27,] 0 0 0 0 0 0 1
[28,] 0 0 0 0 0 0 0
[29,] 0 0 0 0 0 0 0
[30,] 0 0 0 0 0 0 0
[31,] 0 0 0 0 0 0 0
and I change this to a data.frame. set a browser() right before
ggplot(melt(graphPrep),aes(value,fill=variable)) + geom_histogram(position = "dodge",binwidth = 1/(buckWidth-1)) + scale_x_continuous(breaks = min(graphPrep):max(graphPrep))
you can use 5 for buckWidth, and breaks -5:5 if you're replicating
then put that line into R, hit enter, and it makes a nice plot.
However, if I just press "n" a couple times to try to execute that line (or remove the browser entirely), the graph never shows up.
I'd like to make this completely executable from excel, but as-is I'm defining
drawIt <- function()
{
ggplot(melt(graphPrep),aes(value,fill=variable)) + geom_histogram(position = "dodge",binwidth = 1/(buckWidth-1)) + scale_x_continuous(breaks = min(graphPrep):max(graphPrep))
}
and making the user "drawIt()" in the r console. I'd like to just have this work in excel...
as embarrassing as this is, I'm going to leave it up in case others have this same problem
print(drawIt())
Related
I have a matrice that is as such:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] 0 0 0 0 0 0 0 0 0
[2,] 0 0 0 0 0 0 0 0 0
[3,] 0 0 0 0 0 0 0 0 0
[4,] 0 0 0 0 0 0 0 1 1
[5,] 0 0 0 0 0 0 1 1 0
[6,] 0 0 0 0 0 1 0 0 0
[7,] 0 0 0 0 1 1 0 0 0
[8,] 0 0 0 0 1 0 0 0 0
[9,] 0 0 0 0 1 0 0 0 0
[10,] 0 0 0 0 1 1 0 0 0
[11,] 0 0 0 0 0 1 0 0 0
[12,] 0 0 0 0 0 1 1 1 1
[13,] 0 0 0 0 0 0 0 0 0
[14,] 0 0 0 0 0 0 0 0 0
[15,] 0 0 0 0 0 0 0 0 0
[16,] 0 0 0 0 0 0 0 0 0
[17,] 0 0 0 0 0 0 0 0 0
[,10] [,11] [,12] [,13] [,14] [,15] [,16] [,17]
[1,] 0 0 0 0 0 0 0 0
[2,] 0 0 0 0 0 0 0 0
[3,] 0 0 0 0 0 0 0 0
[4,] 1 1 0 0 0 0 0 0
[5,] 0 1 0 0 0 0 0 0
[6,] 0 1 0 0 0 0 0 0
[7,] 0 1 0 0 0 0 0 0
[8,] 0 1 0 0 0 1 0 0
[9,] 0 1 0 0 0 1 0 0
[10,] 1 1 0 0 0 1 0 0
[11,] 1 1 0 1 1 0 0 0
[12,] 1 1 1 1 0 0 0 0
[13,] 0 0 0 0 0 0 0 0
[14,] 0 0 0 0 0 0 0 0
[15,] 0 0 0 0 0 0 0 0
[16,] 0 0 0 0 0 0 0 0
[17,] 0 0 0 0 0 0 0 0
[,18]
[1,] 0
[2,] 0
[3,] 0
[4,] 0
[5,] 0
[6,] 0
[7,] 0
[8,] 0
[9,] 0
[10,] 0
[11,] 0
[12,] 0
[13,] 0
[14,] 0
[15,] 0
[16,] 0
[17,] 0
How can I count the number of rows with exactly 1 value, not more than one?
I've tried using nrow(imageMatrix[imageMatrix < 2])
and also tried converting the matrice to dataframe and then using nrow(dataframe_matrice[dataframe_matrice == 1,])
but it has been of no avail.
Here imageMatrix is the name of the matrice.
Can someone please offer me a hint on what I'm doing wrong with my first line of code in counting rows?
We may use rowSums on a logical matrix (imageMatrix == 1) and then create a logical vector == 1 and get the count with sum
sum(rowSums(imageMatrix == 1) == 1)
imageMatrix <2 is a logical matrix, when it is used to subset the original matrix, it returns a vector of values which doesn't have dim and thus nrow wouldn't work i.e.
nrow(1:5)
NULL
I have a dataset:
time delta
0.47 0
0.01 1
0.30 1
0.07 0
0.38 0
0.68 1
0.13 0
0.09 1
0.08 1
0.04 0
0.13 0
0.41 1
0.22 0
0.11 0
0.85 0
0.26 0
I'm using R and I need to compare this matrix with itself. I want to generate a new matrix 16*16 with values:
1 time_i > time_j & delta_i= delta_j != 0;
0 otherwise.
where i, j = 1,..., 16.
I tried to use the sapply() function, but it is useful only if I want to compare with respect one condition.
Could someone help me? Thank you in advance.
You can use outer to apply a function to every pair of elements in two vectors, so you could do one outer for each of the two logical comparisons, combine them with a logical AND, then convert to numeric. Here I am assuming your matrix is called m:
1*(outer(m[,1], m[,1], `>`) & outer(m[,2], m[,2], function(x, y) x == y & x != 0))
This gives the following output:
#> [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
#> [1,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#> [2,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#> [3,] 0 1 0 0 0 0 0 1 1 0 0 0 0 0
#> [4,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#> [5,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#> [6,] 0 1 1 0 0 0 0 1 1 0 0 1 0 0
#> [7,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#> [8,] 0 1 0 0 0 0 0 0 1 0 0 0 0 0
#> [9,] 0 1 0 0 0 0 0 0 0 0 0 0 0 0
#>[10,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#>[11,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#>[12,] 0 1 1 0 0 0 0 1 1 0 0 0 0 0
#>[13,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#>[14,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#>[15,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#>[16,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0
#> [,15] [,16]
#> [1,] 0 0
#> [2,] 0 0
#> [3,] 0 0
#> [4,] 0 0
#> [5,] 0 0
#> [6,] 0 0
#> [7,] 0 0
#> [8,] 0 0
#> [9,] 0 0
#>[10,] 0 0
#>[11,] 0 0
#>[12,] 0 0
#>[13,] 0 0
#>[14,] 0 0
#>[15,] 0 0
#>[16,] 0 0
You can more easily check that the elements of the matrix are in the correct position by making a matrix of the rows and columns where a 1 is to be found:
which(res == 1, arr.ind = TRUE)
#> row col
#> [1,] 3 2
#> [2,] 6 2
#> [3,] 8 2
#> [4,] 9 2
#> [5,] 12 2
#> [6,] 6 3
#> [7,] 12 3
#> [8,] 3 8
#> [9,] 6 8
#> [10,] 12 8
#> [11,] 3 9
#> [12,] 6 9
#> [13,] 8 9
#> [14,] 12 9
#> [15,] 6 12
The first entry in this table tells us that the criteria were met for row 3 of the original matrix when compared to row 2 of the original matrix. It is easy to confirm that this is indeed the case.
Say that I have a 10 x 5 matrix of zeros in matrix m
m <- matrix(0,10,5)
which looks like this
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 0
[2,] 0 0 0 0 0
[3,] 0 0 0 0 0
[4,] 0 0 0 0 0
[5,] 0 0 0 0 0
[6,] 0 0 0 0 0
[7,] 0 0 0 0 0
[8,] 0 0 0 0 0
[9,] 0 0 0 0 0
[10,] 0 0 0 0 0
now I have a list of coordinates in a matrix called xy:
x y
[1,] 3 1
[2,] 7 3
[3,] 8 1
[4,] 9 4
and I want to update the matrix by taking each row of coordinates above and adding 1 to the cell in matrix m that it refers to -- so the output would then look like this
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 0
[2,] 0 0 0 0 0
[3,] 1 0 0 0 0
[4,] 0 0 0 0 0
[5,] 0 0 0 0 0
[6,] 0 0 0 0 0
[7,] 0 0 1 0 0
[8,] 1 0 0 0 0
[9,] 0 0 0 1 0
[10,] 0 0 0 0 0
Your help is appreciated!
As long as you provide the coordinates as a matrix, 1st column specifiying row, 2nd column specifiying column, you can do:
xy = cbind(c(3,7,8,9),c(1,3,1,4))
m[xy] = 1
[,1] [,2] [,3] [,4] [,5]
[1,] 0 0 0 0 0
[2,] 0 0 0 0 0
[3,] 1 0 0 0 0
[4,] 0 0 0 0 0
[5,] 0 0 0 0 0
[6,] 0 0 0 0 0
[7,] 0 0 1 0 0
[8,] 1 0 0 0 0
[9,] 0 0 0 1 0
[10,] 0 0 0 0 0
Is there a way in R to create binary sets of m, filled with all combinations of n by columns, while by row only 1 value can be "1"?
For example, for n=2 and m=2, we would have the following combinations of m each:
(00, 00), (10,00), (01,00), (00,10), (00,01), (10,01), (01,10), (10,10), (01,01)
But these, for example, are not allowed:
(11,00), (01,11), (00,11), (11,10), (11,11)
This is very similar to your other question. In my answer to that question, we see that rephrasing the question, makes it much easier to attack. So for this question, we can reduce it to: "How to generate all pairwise permutations of powers of 2 with repeats?"
We can use almost exactly the same setup as before, only this time we set the argument repeats.allowed = TRUE.
library(gtools)
bitPairwise2 <- function(numBits, groupSize) {
t(sapply(t(permutations(numBits + 1, groupSize,
c(0, 2^(0:(numBits-1))), repeats.allowed = TRUE)),
function(x) {as.integer(intToBits(x))})[1:numBits, ])
}
bitPairwise2(2,2)
[,1] [,2]
[1,] 0 0 ## (00,00)
[2,] 0 0
[3,] 0 0 ## (00,10)
[4,] 1 0
[5,] 0 0 ## (00,01)
[6,] 0 1
[7,] 1 0 ## (10,00)
[8,] 0 0
[9,] 1 0 ## (10,10)
[10,] 1 0
[11,] 1 0 ## (10,01)
[12,] 0 1
This function generalizes to any number of bits as well as any number of groups. For example, all possible 3-tuples of 3 bits is given by:
## first 9 groups
bitPairwise2(3, 3)[1:27, ]
[,1] [,2] [,3]
[1,] 0 0 0 ## (000,000,000)
[2,] 0 0 0
[3,] 0 0 0
[4,] 0 0 0 ## (000,000,100)
[5,] 0 0 0
[6,] 1 0 0
[7,] 0 0 0 ## (000,000,010)
[8,] 0 0 0
[9,] 0 1 0
[10,] 0 0 0 ## (000,000,001)
[11,] 0 0 0
[12,] 0 0 1
[13,] 0 0 0 ## (000,100,000)
[14,] 1 0 0
[15,] 0 0 0
[16,] 0 0 0 ## (000,100,100)
[17,] 1 0 0
[18,] 1 0 0
[19,] 0 0 0 ## (000,100,010)
[20,] 1 0 0
[21,] 0 1 0
[22,] 0 0 0 ## (000,100,001)
[23,] 1 0 0
[24,] 0 0 1
[25,] 0 0 0 ## (000,010,000)
[26,] 0 1 0
[27,] 0 0 0
And here are the last 9 groups:
a <- bitPairwise2(3, 3)[166:192, ]
row.names(a) <- 166:192
a
[,1] [,2] [,3]
166 0 0 1 ## (001,100,001)
167 1 0 0
168 0 0 1
169 0 0 1 ## (001,010,000)
170 0 1 0
171 0 0 0
172 0 0 1 ## (001,010,100)
173 0 1 0
174 1 0 0
175 0 0 1 ## (001,010,010)
176 0 1 0
177 0 1 0
178 0 0 1 ## (001,010,001)
179 0 1 0
180 0 0 1
181 0 0 1 ## (001,001,000)
182 0 0 1
183 0 0 0
184 0 0 1 ## (001,001,100)
185 0 0 1
186 1 0 0
187 0 0 1 ## (001,001,010)
188 0 0 1
189 0 1 0
190 0 0 1 ## (001,001,001)
191 0 0 1
192 0 0 1
If you need the output in a list, try this:
test <- bitPairwise2(4, 3)
numGroups <- nrow(test)/3
makeGroupList <- function(mat, nG, groupSize) {
lapply(1:nG, function(x) {
s <- groupSize*(x-1) + 1
e <- s + (groupSize - 1)
mat[s:e, ]
})
}
makeGroupList(test, numGroups, 3)
[[1]]
[,1] [,2] [,3] [,4]
[1,] 0 0 0 0
[2,] 0 0 0 0
[3,] 0 0 0 0
[[2]]
[,1] [,2] [,3] [,4]
[1,] 0 0 0 0
[2,] 0 0 0 0
[3,] 1 0 0 0
[[3]]
[,1] [,2] [,3] [,4]
[1,] 0 0 0 0
[2,] 0 0 0 0
[3,] 0 1 0 0
. . . . .
. . . . .
. . . . .
I have a large dataframe with each column containing one flag from the set {-1,1}, all the rest of the values are set to zero. I want to fill up or down the rest of the column entries with a value corresponding to that flag value. for example, given a vector to represent 1 column, I have
v <- rep(0,15)
v[12] <- 1
#I'd want a function that is something like:
f <- function(v,flag){
for(i in 2:length(v)){ if(v[i-1]==flag) v[i] <- flag else v[i]<-v[i]}
v
}
> v
[1] 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
> f(v,1)
[1] 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
The example works fine for filling forward some v and a flag 1. I'd also want to be able to fill backwards with 1 based on a -1 flag. The obvious solution that comes to mind is na.locf, except I can't get it to work with a 1 in the middle and filling forward and backwards. Even if I populate the 0 elements with NA, it will still not partially fill up or down based on a flag.
Are there any simple and fast vectorized functions that could do this with a matrix or zoo object populated with all zeros, except where there is one element with 1 or -1 in each column, telling it to fill down or up with 1s depending on the value?
edit: thinking about it a bit more, I came up with a possible solution, that along with an illustration, (hopefully) makes it more clear what I want.
Also, the overall goal is to create a mask for Additions/Deletions to a fund index, by date, that fill forwards for additions (+1) and fill backwards for removals (-1). Also, why I thought of na.locf right away. Still not sure if this is the best approach for this block, though. Any thoughts appreciated.
#generate random matrix of flags
v.mtx <- matrix(0,15,10)
for(i in 1:10){
v.mtx[sample(1:15,1),i] <- sample(c(-1,1),1)
}
fill.flag <- function(v) {
if(any(-1 %in% v)) {v[1:which(v!=0)] <- 1}
else
if(any(1 %in% v)) {v[which(v!=0):length(v)] <- 1}
v
}
> v.mtx
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 0 0 0 0 0 1 0 0 0 0
[2,] 0 0 0 0 0 0 0 0 0 0
[3,] 0 0 0 0 0 0 0 0 0 0
[4,] 0 0 0 0 0 0 0 0 0 0
[5,] 0 0 0 0 0 0 0 0 0 0
[6,] 0 0 0 0 1 0 -1 0 0 0
[7,] 0 0 0 -1 0 0 0 0 0 0
[8,] 0 0 0 0 0 0 0 0 0 0
[9,] 0 0 0 0 0 0 0 1 0 -1
[10,] 0 0 0 0 0 0 0 0 -1 0
[11,] 0 0 0 0 0 0 0 0 0 0
[12,] 0 0 0 0 0 0 0 0 0 0
[13,] 0 0 1 0 0 0 0 0 0 0
[14,] 0 0 0 0 0 0 0 0 0 0
[15,] 1 -1 0 0 0 0 0 0 0 0
> apply(v.mtx,2,fill.flag)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 0 1 0 1 0 1 1 0 1 1
[2,] 0 1 0 1 0 1 1 0 1 1
[3,] 0 1 0 1 0 1 1 0 1 1
[4,] 0 1 0 1 0 1 1 0 1 1
[5,] 0 1 0 1 0 1 1 0 1 1
[6,] 0 1 0 1 1 1 1 0 1 1
[7,] 0 1 0 1 1 1 0 0 1 1
[8,] 0 1 0 0 1 1 0 0 1 1
[9,] 0 1 0 0 1 1 0 1 1 1
[10,] 0 1 0 0 1 1 0 1 1 0
[11,] 0 1 0 0 1 1 0 1 0 0
[12,] 0 1 0 0 1 1 0 1 0 0
[13,] 0 1 1 0 1 1 0 1 0 0
[14,] 0 1 1 0 1 1 0 1 0 0
[15,] 1 1 1 0 1 1 0 1 0 0
As #G. Grothendieck commented, you can try cummax and cummin, i.e.
f1 <- function(x){
if(sum(x) == 1){
return(cummax(x))
}else{
return(rev(cummin(rev(x)))* -1)
}
}
#apply as usual
apply(v.mtx, 2, f1)