Assign values to random cells in raster - raster

I was wondering if there is a way to assign a value to a predetermined number of cells at random locations within a raster?
For example, if I wanted to assign
a value of '10' to 3 cells at random locations for cells with a value of '1' in a raster
a value of '20' to 4 cells at random locations for cells with a value of '1' in a raster
a value of '40' to 10 cells at random locations for cells with a value of '1' in a raster
What is the best way to do this? And, are there any examples/scripts that already exist?
For example the original raster below:
and the output:
Thanks!!

All sorted now :)
c = np.random.random((10,10)).round(0).astype(int)
c_idx = np.arange(c.size)[c.flatten()==1]
np.random.shuffle(c_idx)
d = c.flatten()
d[c_idx[:3]] = 10
d[c_idx[3:7]] = 20
d[c_idx[7:17]] = 40
d = d.reshape(c.shape)
d

Related

How to perform the equivalent of Excel minifs in R dplyr?

I am slowly transitioning from XLS to R. In the below reproducible code, I would like to add columns for "MinIfs" using dplyr as detailed in the below image, whereby the Excel minifs() formula in column G of the image has conditions with only the tops of the specified ranges "anchored", for a "rolling" calculation as you move down row-wise; and the minifs() formula in column M with the same conditions but with the entire range of the reference array fixed and not "rolling". Any recommendations for doing this in dplyr? Dplyr works for the equivalent XLS sumifs() in columns E and F. The blue below shows the current reproducible code output, the yellow shows what I would like to add, and the non-highlighted shows the underlying XLS formulas for the cells in yellow to the immediate left of each.
Now using words:
to derive Rolling MinIfs (call it RollMinIfs), for each row
one-at-a-time rolling from top-to-bottom of the array sequentially,
show the minimum value in column C from the top of the column C range
to the current row in the Column C range that has a column D "Code2"
value in the range D4:D6 not equal to the 0. So for
example in deriving the value of -5 in cell G6: cell C6 has the
lowest value in the range C4:C6 whereby the corresponding Code2
values in range D4:D6 are not equal to 0; and
to derive Fixed MinIfs
(call it FixMinIfs), for all rows in the array fixed range C4:C10, show the minimum value in Column C that has a corresponding column D "Code2" value not equal to 0.
Reproducible code:
library(dplyr)
myDF <-
data.frame(
Name = c("B","R","R","R","R","B","A"),
Group = c(0,1,1,2,2,0,0),
Code1 = c(0,1,-5,3,3,4,-8),
Code2 = c(1,0,2,0,1,2,1)
)
myDFRender <-
myDF %>%
mutate(RollSumIfs = sapply(1:n(), function(x) sum(Code2[1:x][Code1[1:x] < Code1[x]]))) %>%
mutate(FixSumIfs = sapply(1:n(), function(x) sum(Code2[1:n()][Code1[1:n()] < Code1[x]])))
print.data.frame(myDFRender)

How to split a heat map or a draw a boundary with specific range?

I have a expression matrix containing three groups. I need to draw or split the heat-map with specific range of column.
Total number of colums: 151 where 1st column is gene ids
Group1: 2:40
Group2: 41:80
Group3: 81:151
I searched for splitting the heatmap and I got some hits like this.
But they are based on specific clusters.
I need to give my range as (2:40, 41:80, 81:151) for splitting or making boundary for the heatmap
Something like this
library(pheatmap)
mat = cbind(genes=1:100,
matrix(rnorm(150*100,mean = rep(1:3,c(39*100,40*100,71*100))),ncol=150))
colnames(mat)[2:ncol(mat)] = paste0("col",1:150)
You need to know how many are in each group, from what you provided, i counted this:
Group1: 39 Group2: 40 Group3: 71
So you need to make a data.frame that has the same row names as your matrix, and tell it which is group1,2 etc.
DF = data.frame(Groups=rep(c("Group1","Group2","Group3"),c(39,40,71)))
rownames(DF) = colnames(mat)[2:ncol(mat)]
Then we plot, mat[,-1] means excluding the first column, you need to specify where to insert the gap, and for your example it is at 39,79 and 80 because we excluded the first column:
pheatmap(mat[,-1],cluster_cols=FALSE,
annotation_col=DF,gaps_col = cumsum(c(39,40,71)))

R index variable shrunk to number of unique groups

I have a data frame, dat, with 214 rows of data. Each row contains these variables: Species and Mode either red or green. I have sorted the data by Species. I would like to create a numeric index variable where if mode is red then index = 0 else index = 1.
Further, the index can only be as long as the unique number of species that exist (N=72), such that, if there are 5 of speciesA, red and 7 of speciesB, green that is a red species, then row 1 = 0 and row 2 = 1and so on. Here is the code I have tried so far:
index <- for (q in 1:unique(species)) {
ifelse(mode[q]=='red',0,1)
}
index <- as.numeric(factor(my_dataframe$mode))
A factor, under the hood, is stored as an integer. So the conversion from factor to numeric index is 1 to 1.

How do I extract a series of n rows after initial row extraction?

Suppose I have matrix called M,
"Date" "X" "Y"
1991 T 10
1992 T 5
1993 F 2
1994 F 1
1995 T 7
where date is a character value, X is Boolean, and Y is numeric. Also, assume that the total number of rows are 50, each filled with values mentioned above.
My initial selection criteria is for the second column to be True. Thus,
initial_row<-M[M[,2]==T,]
I am looking for a way to extract 10 rows (or any constant number) following the initial row, regardless of their values on any column. Basically, I'm trying to mine all the rows that follow the initial extraction, then move on until next row that meets the initial selection criteria.
This code should extract the rows following the initial rows and put the batches of rows into a list
const <- 10
lapply(which(M$X), function(n){
indices <- n + 1:const # 0:const to include initial row
indices <- indices[indices <= nrow(M)] # exclude out of bounds values
M[indices,]
})

Subtract column-specific value for a particular row from all values in data frame, in R

I have a data object signal in R with 40,000+ rows (named variables) of numeric values and 200+ columns (samples). For every row of each column, I want to subtract the value for the row named background for that column.
The code below can be used to create an example signal object in R. With the example, for column A, the background value of 4 is to be subtracted from the values of channelNo1 to 3. Similarly, for column B, the value of 6 is to be subtracted. And so on. What is the simplest way to achieve this in R?
text <- textConnection('
A B C
channelNo1 12 22 32
channelNo2 13 21 33
channelNo3 12 21 30
background 4 6 8
')
signal <- read.table(text, header = TRUE)
close(text)
typeof(signal)
# returns 'list'
class(signal)
# returns 'data.frame'
Elements in an R matrix are oriented by column (check out matrix(1:12, nrow=3) and signal - signal[4,] is not doing what you think -- check out column B, where the second and third values should be the same (and equal to 15). You could write
as.data.frame(Map("-", signal, as.vector(signal[4,])))
(I think this would be relatively efficient) but since the data really seem to be a matrix (i.e., a rectangle of homogeneous type) it makes a lot more sense to manipulate it as a matrix
m = as.matrix(signal)
sweep(m, 2, m[4,], "-")

Resources