In place modification of matrices in R
I get the same behaviour as the OP using R 3.2.0 running within RStudio 0.99.441 on Windows 8.1 and using pryr::address
. The issue is RStudio has a reference to y for its Environment pane. As often the case, Hadley Wickham has some excellent documentation of this.
I don't think there's any way around this for matrices in the global environment other than not using RStudio. I've tried a couple of other things. Matrices within a function are fine:
library("pryr")
fn <- function() {
y <- matrix(c(11,21,31,12,22,32),nrow=3,ncol=2)
print(address(y))
y[2:3,] <- matrix(c(1,1,8,12),nrow=2)
print(address(y))
}
Calling fn()
should show that the address is unchanged.
However, creating y as a member of a list or environment which are in the global environment doesn't prevent the copy on write (e.g. x <- new.env(); x$y <- matrix(...)
).
Per Is there any way to disable environment pane in RStudio? there doesn't seem to be any way of disabling the environment pane.
data.table
still manages to avoid unncessarily copies. Try:
library("data.table")
x <- as.data.table(matrix(c(11,21,31,12,22,32),nrow=3,ncol=2))
address(x)
x[2:3, `:=`(V1 = c(1, 1), V2 = c(8, 12))]
address(x)
x[, V3 := V1 + V2]
address(x)
How to assign row changes to an existing matrix within an 'apply' function from the parallel package
You can't assign in parallel, as you're just assigning to a local copy of the matrix.
Two solutions:
Use shared memory (e.g. matrices on disk using package {bigstatsr}; disclaimer: I'm the author)
Don't assign in the first place. Just run the
lapply()
, get all the results parts as a list and usedo.call("rbind", list)
.
Modifying an element in a list of matrices
I would just do a for
loop, easy and clear:
for(i in seq_along(AA)) {
AA[[i]][1, 3] = AA[[i]][1, 3] * i / length(AA)
}
Function to return modified matrix in R
The assignment is happening within the function's environment, not the global one. You need to return the result in the function, and assign it with the function call. Try this:
addfunction <- function(x){
x$XTSSum2 <- x$XTS1 + lag(x$XTS1,1)
x
}
XTS1 <- addfunction(XTS1)
Modifying an matrix surrounding elements of an element?
You are checking if the value is 2 and not 1 like it is in your example the y[row,col] == 2
. This needs to be changed to y[row,col] == 1
if you want the example in the question to work correctly.
You can also add if
statements to check if the position you want to change is out of bounds.
y <- mat
for(row in 1:nrow(y)){
for(col in 1:ncol(y)){
if(y[row,col] == 1){
if(row > 1){
if(col > 1){
y[row-1,col] <- sample(c(0,1), replace = TRUE, size = 1)
y[row,col-1] <- sample(c(0,1), replace = TRUE, size = 1)
y[row-1,col-1] <- sample(c(0,1), replace = TRUE, size = 1)
}
if(col < ncol(y)){
y[row-1,col+1] <- sample(c(0,1), replace = TRUE, size = 1)
y[row,col+1] <- sample(c(0,1), replace = TRUE, size = 1)
}
}
if(row < nrow(y)){
if(col > 1){
y[row+1,col] <- sample(c(0,1), replace = TRUE, size = 1)
y[row+1,col-1] <- sample(c(0,1), replace = TRUE, size = 1)
}
if(col < ncol(y)){
y[row+1,col+1] <- sample(c(0,1), replace = TRUE, size = 1)
}
}
}
}
}
In R how would you replace values in a matrix that have a certain condition with values from another vector?
Thought you had to use apply(Matrix, \(x) pmin(x, Vector))
, but actually, you can just use pmin()
directly on your Matrix
because it will recycle the Vector
to match the length.
pmin(Matrix, Vector)
#> [,1] [,2]
#> [1,] 2 2
#> [2,] 3 3
#> [3,] 3 2
#> [4,] 1 1
Does R copy an entire matrix while modifying?
It seems the object does not get copied in this case. You can use the base::tracemem()
function:
mat <- matrix(7,10,10)
mat_filter <- cbind(c(1,6,10),
c(1,5,3))
tracemem(mat)
[1] "<0x7fa68bfde840>"
This returns the current memory address of mat
, and will print any change in address, if one occurs.
mat[mat_filter] <- mat[mat_filter] + 1
produces no tracemem
output, so the modification should be happening in place.
Hadley Wickham's Advanced R has a chapter on this.
Change elements in one matrix based on positions given by another matrix in R
You want to do something like matrix subsetting (e.g., P[Q]
) except that you can't use negative indexing in matrix subsetting (e.g., P[-Q]
is not allowed). Here's a work-around.
Store the elements you want to retain from A
in a 2-column matrix where each row is a coordinate of A
:
Idx <- cbind(rep(1:4, each=ncol(B)), as.vector(t(B)))
Create a matrix where all values are Inf
, and then overwrite the values you wanted to "keep" from A
:
Res <- matrix(Inf, nrow=nrow(A), ncol=ncol(A))
Res[Idx] <- A[Idx]
Result
Res
# [,1] [,2] [,3] [,4]
#[1,] 0.9043131 0.639718071 Inf 0.19158238
#[2,] 0.6397181 0.601327568 0.007363378 Inf
#[3,] Inf 0.007363378 0.752123162 0.61428003
#[4,] 0.1915824 Inf 0.614280026 0.02932679
Manipulation List of Matrices in R
Try
lapply(L, function(x) diag(rowSums(x))-x)
data
set.seed(25)
L <- lapply(1:5, function(i) matrix(sample(1:20, 4*4,
replace=TRUE), ncol=4))
Related Topics
Assign Color to 2 Different Geoms and Get 2 Different Legends
Handling Missing Combinations of Factors in R
Replace All Values Lower Than Threshold in R
Extract Names of Dataframes Passed with Dots
Creating "Word" Cloud of Phrases, Not Individual Words in R
Make Legend Invisible But Keep Figure Dimensions and Margins the Same
Creating Sequence of Dates for Each Group in R
Dummy Variables to Single Categorical Variable (Factor) in R
Mass Variable Declaration and Assignment in R
How to Determine If a Url Object Returns '404 Not Found'
Set Standard Legend Key Size with Long Label Names Ggplot
Convert an Integer Column to Time Hh:Mm
R: Fast (Conditional) Subsetting Where Feasible
R: How to Get a Sum of Two Distributions
Ggplot Line Plot Different Colors for Sections
Ggplot2: Geom_Smooth Confidence Band Does Not Extend to Edge of Graph, Even with Fullrange=True