How do I find peak values/row numbers? - r

I have a large dataset (202k points). I know that there are 8 values over 0.5. I want to subset on those rows.
How do I find/return a list the row numbers where the values are > 0.5?

If the dataset is a vector named x:
(1:length(x))[x > 0.5]
If the dataset is a data.frame or matrix named x and the variable of interest is in column j:
(1:nrow(x))[x[,j] > 0.5]
But if you just want to find the subset and don't really need the row numbers, use
subset(x, x > 0.5)
for a vector and
subset(x, x[,j] > 0.5)
for a matrix or data.frame.

which(x > 0.5)

Here's some dummy data:
D<-matrix(c(0.6,0.1,0.1,0.2,0.1,0.1,0.23,0.1,0.8,0.2,0.2,0.2),nrow=3)
Which looks like:
> D
[,1] [,2] [,3] [,4]
[1,] 0.6 0.2 0.23 0.2
[2,] 0.1 0.1 0.10 0.2
[3,] 0.1 0.1 0.80 0.2
And here's the logical row index,
index <- (rowSums(D>0.5))>=1
You can use it to extract the rows you want:
PeakRows <- D[index,]
Which looks like this:
> PeakRows
[,1] [,2] [,3] [,4]
[1,] 0.6 0.2 0.23 0.2
[2,] 0.1 0.1 0.80 0.2

Using the argument arr.ind=TRUE with which is a great way for finding the row (or column) numbers where a condition is TRUE,
df <- matrix(c(0.6,0.2,0.1,0.25,0.11,0.13,0.23,0.18,0.21,0.29,0.23,0.51), nrow=4)
# [,1] [,2] [,3]
# [1,] 0.60 0.11 0.21
# [2,] 0.20 0.13 0.29
# [3,] 0.10 0.23 0.23
# [4,] 0.25 0.18 0.51
which with arr.ind=TRUE returns the array indices where the condition is TRUE
which(df > 0.5, arr.ind=TRUE)
row col
[1,] 1 1
[2,] 4 3
so the subset becomes
df[-which(df > 0.5, arr.ind=TRUE)[, "row"], ]
# [,1] [,2] [,3]
# [1,] 0.2 0.13 0.29
# [2,] 0.1 0.23 0.23

Related

Sum values in matrix with R (only above diagonal)

I have a matrix with 50 rows and 50 columns:
[,1] [,2] [,3]...[,50]
[1,] 1 0.8 0.7
[2,] 0.8 1 0.5
[3,] 0.7 0.5 1
...
[50,]
And I want to sum 0.02 in values up to diagonal to obtain something like this:
[,1] [,2] [,3]...[,50]
[1,] 1 0.82 0.72
[2,] 0.8 1 0.52
[3,] 0.7 0.5 1
...
[50,]
Does anyone know how the sum could be done only in the values that are above the diagonal of the matrix using R?
Example of matrix code:
matrix <- as.matrix(data.frame(A = c(1, 0.8, 0.7), B = c(0.8, 1, 0.5), C = c(0.7, 0.5, 1)), nrow=3, ncol=3)
Try upper.tri like below
matrix[upper.tri(matrix)] <- matrix[upper.tri(matrix)] + 0.02
You can use lower.tri(m) or upper.tri(m) functions in R. Which m is your matrix.
m = matrix(1:36, 6, 6)
m[upper.tri(m)] = m[upper.tri(m)] + 0.02
m

Maximum and minimum values in matrix R [duplicate]

This question already has answers here:
Use max on each element of a matrix
(3 answers)
Closed 5 years ago.
I have a 3D matrix of float values, and I need the maximum and minimum values inside, like:
[[1]]
0.1 0.3 0.6 0.8
0.09 0.1 0.4 0.6
[[2]]
0.08 0.2 0.5 0.75
0.01 0.3 0.5 0.55
generated by:
m <- list(matrix(c(0.1,0.3,0.6,0.8,
0.09,0.1,0.4,0.6),2,4,byrow=TRUE),
matrix(c(0.08,0.2,0.5,0.75,
0.01,0.3,0.5,0.55),2,4,byrow=TRUE))
max is 0.8 and min 0.01
I try max() and min() functions but doesn't work..
Try this:
Toy data:
> m1<-matrix(runif(8,1,100),2,4)
> m1
[,1] [,2] [,3] [,4]
[1,] 98.88260 97.13486 2.712315 35.09616
[2,] 43.90468 99.59167 41.873303 94.19843
> m2<-matrix(runif(8,1,100),2,4)
> m2
[,1] [,2] [,3] [,4]
[1,] 26.61785 61.11184 42.28846 55.87778
[2,] 49.27263 59.28607 46.72659 76.24321
> l<-list(m1,m2)
Calculate max and min
> lapply(l,FUN = max)
[[1]]
[1] 99.59167
[[2]]
[1] 76.24321
> lapply(l,FUN = min)
[[1]]
[1] 2.712315
[[2]]
[1] 26.61785
Also, you can have both in one line of code: lapply(l,FUN = range) (Thanks to Joseph Wood for this last suggestions. See comments)

Pasting a string matrix row-wise with a string vector

I am trying to concatenate multcompView letters with summary data into a matrix. I am using a for loop to run through the individual summary matrix cells and concatenate these with their respective letters. I am almost there but my matrix outputs both the original data and the pasted data (see below).
Function:
for (i in 1:nrow(X1))
tableRow = matrix(c(tableRow,paste(tableRow[i],letters$Letters[i],sep = "")),nrow = 1)
Where:
X1 is my summary table, tableRow is the first row of X1, and
letters contains the letter I want to concatenate with.
Returns:
[1,] "5.53 ± 0.77" "6.72 ± 1.18" "5.12 ± 0.44"
"5.24 ± 0.41" "5.53 ± 0.77a" "6.72 ± 1.18a" "5.12 ± 0.44a" "5.24 ± 0.41a"
Desired output:
[1,] "5.53 ± 0.77a" "6.72 ± 1.18a" "5.12 ± 0.44a" "5.24 ± 0.41a"
This will do all the work:
## example matrix
set.seed(0); X <- round(matrix(runif(12), nrow = 4, ncol = 3), 2)
# [,1] [,2] [,3]
# [1,] 0.90 0.91 0.66
# [2,] 0.27 0.20 0.63
# [3,] 0.37 0.90 0.06
# [4,] 0.57 0.94 0.21
matrix(paste0(X, letters[1:4]), nrow = nrow(X))
# [,1] [,2] [,3]
# [1,] "0.9a" "0.91a" "0.66a"
# [2,] "0.27b" "0.2b" "0.63b"
# [3,] "0.37c" "0.9c" "0.06c"
# [4,] "0.57d" "0.94d" "0.21d"
For your data, you can do:
matrix(paste0(X1, letters$Letters), nrow = nrow(X1))
Remark 1
My example here has some defect. You already have X1 as a character matrix, while my example X is numeric. When doing paste0(), numerical value 0.90 becomes "0.9" (because as.character(0.90) gives "0.9"). For your data there will be no such behaviour.
Remark 2
Oh, I actually find a way to avoid such behaviour.
X <- format(X)
# [,1] [,2] [,3]
# [1,] "0.90" "0.91" "0.66"
# [2,] "0.27" "0.20" "0.63"
# [3,] "0.37" "0.90" "0.06"
# [4,] "0.57" "0.94" "0.21"
Then doing paste0() is OK:
# [,1] [,2] [,3]
# [1,] "0.90a" "0.91a" "0.66a"
# [2,] "0.27b" "0.20b" "0.63b"
# [3,] "0.37c" "0.90c" "0.06c"
# [4,] "0.57d" "0.94d" "0.21d"

Create single list from two data frames while preserving class of columns and its names

I have two data frames:
DF1
e l u
1 0.5 1.5
2 1 3
3 2 4
DF2
e l u
0.1 0.01 0.15
0.2 0.1 0.3
0.3 0.2 0.4
I want to combine these two data frames into single list like so:
L
[[1]]
$e: [(1 0.1);(2 0.2);(3 0.3)] #numeric
$l: [(0.5 0.01);(1 0.1);(2 0.2)] #numeric
$u: [(1.5 0.015);(3 0.3);(4 0.4)] #numeric
I have tried to rbind two data frames and then split by same column, also i was advised to use Map but it results in multiple lists not a single one or all variables become factors.
Thank you for any suggestions.
It looks like you want a list of arrays.
> mapply(cbind, DF1, DF2, SIMPLIFY=FALSE)
$e
[,1] [,2]
[1,] 1 0.1
[2,] 2 0.2
[3,] 3 0.3
$l
[,1] [,2]
[1,] 0.5 0.01
[2,] 1.0 0.10
[3,] 2.0 0.20
$u
[,1] [,2]
[1,] 1.5 0.15
[2,] 3.0 0.30
[3,] 4.0 0.40

subset matrices: map a binary matrix onto a qualitative matrix for 1s but not 0s while keeping matrix dimension intact

Lets say I have two list-of-lists, one being solely binary and the other one being quantitative. The order in the lists matters. I would like to map the binary matrices onto its qualitatively counterpart while creating a new list-of-lists with the same number of nested matrices with the same dimensions. These matrices will be subsets of their qualitative counterparts; where there are 1s in the binary matrices.
# dummy data
dat1 <- c(0,1,0,1,1,0,0,0,1,0,0,0,1,1,0,1)
mat1 <- matrix(dat1, ncol=4, nrow=4, byrow=T)
dat2 <- c(1,1,0,1,0,0,1,1,0,1,0,1,0,1,0,0)
mat2 <- matrix(dat1, ncol=4, nrow=4, byrow=T)
lsMat1 <- list(mat1, mat2)
dat3 <- c(0.3,0.1,0.6,0.3,0.9,0.1,0.1,0.3,0.6,0.2,0.7,0.8,0.4,0.1,0.4,0.5)
mat3 <- matrix(dat3, ncol=4, nrow=4, byrow=T)
dat4 <- c(0.5,0.3,0.6,0.8,0.1,0.4,0.5,0.1,0.5,0.1,0.0,0.1,0.4,0.6,0.0,0.8)
mat4 <- matrix(dat4, ncol=4, nrow=4, byrow=T)
lsMat2 <- list(mat3, mat4)
Desired new nested list
[[1]]
[,1] [,2] [,3] [,4]
[1,] 0.0 0.1 0 0.3
[2,] 0.9 0.0 0 0.0
[3,] 0.6 0.0 0 0.0
[4,] 0.4 0.1 0 0.5
[[2]]
[,1] [,2] [,3] [,4]
[1,] 0.0 0.3 0 0.8
[2,] 0.1 0.0 0 0.0
[3,] 0.5 0.0 0 0.0
[4,] 0.4 0.6 0 0.8
Any pointers would be highly appreciated, thanks!
I'm going to assume the output you supplied above is incorrect. Since you have 0's and 1's in your binary matrix and you only want to keep the 1's values, you can use simple elementwise multiplication. You can do that for each item in the list with
Map(`*`, lsMat1, lsMat2)
which returns
[[1]]
[,1] [,2] [,3] [,4]
[1,] 0.0 0.1 0 0.3
[2,] 0.9 0.0 0 0.0
[3,] 0.6 0.0 0 0.0
[4,] 0.4 0.1 0 0.5
[[2]]
[,1] [,2] [,3] [,4]
[1,] 0.0 0.3 0 0.8
[2,] 0.1 0.0 0 0.0
[3,] 0.5 0.0 0 0.0
[4,] 0.4 0.6 0 0.8
given that column three in both matrices in lsMat1 are all 0, this seems more correct.
If i understood the question i would do a element-wise matrix multiplication. Im not familiar with the syntax you posted but IN MATLAB:
mat1 .* mat3
Now all elements that are zero in your binary matrix will stay zero, and all that are one will become the value from your qualitative matrix.
Hope it helps!

Resources