I've got a list called res that looks like this:
[[1]]
[,1] [,2]
[1,] 275.0637 273.9386
[2,] 5.707791 5.755798
[[2]]
[,1] [,2]
[1,] 126.8435 59.08806
[2,] 4.867521 3.258545
[[3]]
[,1] [,2]
[1,] 23.50188 60.96321
[2,] 2.036354 3.737291
The list contains results from a simulation run a total of 6 times. I set a parameter of interest at three different values, '0' (ie., [[1]]), '25' (i.e.,[[2]]), and '50' (i.e.,[[3]]). Since the model includes a great deal of randomness I ran the model twice for each value (i.e., [,1], [,2]). I asked the model to record two results, 'time feeding' (i.e., [1,] and 'distance traveled' (i.e., [2,]) for each iteration. Ultimately I will iterate the model 30 times for each variable setting. I'd like to use ggplot to create a boxplot showing 'time feeding' and 'distance traveled' for each of the three simulation settings (i.e., 0,25,50). I believe ggplot can't plot a list so I tried to convert res to a dataframe using res2 <- data.frame(res) which looked like:
X1 X2 X1.1 X2.1 X1.2 X2.2
1 275.0637 273.9386 126.8435 59.08806 23.50188 60.96321
2 5.707791 5.755798 4.867521 3.258545 2.036354 3.737291
This doesn't quite look right to me because now the results from all three simulations are on the same row. Any help on bringing this data into ggplot to create a boxplot with would be really helpful. Thanks in advance!
--Neil
Assuming ll is your list , you can use do.call and rbind like this :
do.call(rbind,lapply(seq_along(ll),
function(x)data.frame(ll[[x]],iter=x)))
X..1. X..2. iter
[1,] 275.063700 273.938600 1
[2,] 5.707791 5.755798 1
[1,]1 126.843500 59.088060 2
[2,]1 4.867521 3.258545 2
[1,]2 23.501880 60.963210 3
[2,]2 2.036354 3.737291 3
EDIT after op clarication:
interest <- c(0,25,50)
do.call(rbind,lapply(seq_along(ll),
function(x)data.frame(x= unlist(ll[[x]]),interst=interest[x])))
interst=interest[x] .... [TRUNCATED]
x interst
X..1.1 275.063700 0
X..1.2 5.707791 0
X..2.1 273.938600 0
X..2.2 5.755798 0
X..1.11 126.843500 25
X..1.21 4.867521 25
X..2.11 59.088060 25
X..2.21 3.258545 25
X..1.12 23.501880 50
X..1.22 2.036354 50
X..2.12 60.963210 50
X..2.22 3.737291 50
EDIT since OP don't provide data here ll :
res <- list(read.table(text='
[,1] [,2]
[1,] 275.0637 273.9386
[2,] 5.707791 5.755798'),
read.table(text='
[,1] [,2]
[1,] 126.8435 59.08806
[2,] 4.867521 3.258545'),
read.table(text='
[,1] [,2]
[1,] 23.50188 60.96321
[2,] 2.036354 3.737291'))
I would do
names(res) = c("0", "25", "50")
m = reshape2::melt(res, id = 1)
but maybe it doesn't work, I tried it in my head because you didn't provide data in usable form.
Related
I have two matrices:For example
temp1 <- matrix(c(1,2,3,4,5,6),2,3,byrow = T)
temp2 <- matrix(c(7,8,9),1,3,byrow = T)
temp1
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
temp2
[,1] [,2] [,3]
[1,] 7 8 9
I have two matrices with the same number of rows, but with different rows. I would like to add these two matrices as follows. I wonder if there is a way to add R without for statements and apply functions.
temp <- do.call(rbind,lapply(1:2,function(x){temp[x,]+temp2}))
temp
[,1] [,2] [,3]
[1,] 8 10 12
[2,] 11 13 15
This example is simple, but in practice I need to do the above with a 100 * 100 matrix and a 1 * 100 matrix. In this case, it takes too long, so I do not want to use for statements and apply functions.
You can use ?sweep:
temp1 <- matrix(c(1,2,3,4,5,6),2,3,byrow = T)
temp2 <- matrix(c(7,8,9),1,3,byrow = T)
sweep(temp1, 2, temp2, '+')
Unfortunately the help for sweep is really difficult to understand, but in this example you apply the function ´+´ with argument ´temp2´ along the second dimension of temp1.
For more examples, see: How to use the 'sweep' function
This question already has an answer here:
Solve homogenous system Ax = 0 for any m * n matrix A in R (find null space basis for A)
(1 answer)
Closed 4 years ago.
I am using the pracma package, which contains the function nullspace(), returning normalized basis vectors of the Null(A):
> require(pracma)
> (A = matrix(c(1,2,3,4,5,6), nrow=2, byrow=T))
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
> nullspace(A)
[,1]
[1,] 0.4082483
[2,] -0.8164966
[3,] 0.4082483
which is perfectly fine. However (don't ask), I want to quickly check the values I'd get if I were to produce the reduced row echelon form:
> rref(A)
[,1] [,2] [,3]
[1,] 1 0 -1
[2,] 0 1 2
and from there "manually" figure out the null space as
N(A) = [1, -2, 1]'
Yes, the latter is a scalar multiple of the former:
> c(1,-2,1)/nullspace(A)
[,1]
[1,] 2.44949
[2,] 2.44949
[3,] 2.44949
but I'd still like to get the latter, non-normalized form of a basis of the null space, as though the values were directly obtained from the reduced row echelon matrix.
You may want to try
B = rref(A)
solve(B[,1:2], -B[,3])
This gives you the combination your need for the first two columns to get one unit of the third column. Just add one to get your result.
Similarly for the case where size of null space is larger than one.
I have created a list like the following one that contains all combinations of a specific character inside a string. The code that creates the list is as follows :
library(stringr)
test = str_locate_all("TTEST" , "T")
ind1 = lapply( lapply(1:nrow(test[[1]]), combn , x=test[[1]][,1]) , t )
ind1[[1]] = rbind(ind1[[1]], 0 )
and the list that I'm getting looks like
[[1]]
[,1]
[1,] 1
[2,] 2
[3,] 5
[4,] 0
[[2]]
[,1] [,2]
[1,] 1 2
[2,] 1 5
[3,] 2 5
[[3]]
[,1] [,2] [,3]
[1,] 1 2 5
what I want now is to combine/collapse the columns (where ever are more than one) and unlist the whole object in order to create a final vector that will look like c(1, 2, 5, 0, 1:2, 1:5, 2:5, 1:2:5 ) and be able to use it with expand.grid() function later.
Tried to solve it with the following code partially but ":" character went on different position than the wanted.
do.call(paste, c( as.data.frame(ind1[[2]]) ,collapse=":") )
[1] "1 2:1 5:2 5"
Here is an idea via base R where we convert the list elements to data frames and use do.call to paste them, i.e.
unlist(lapply(ind1, function(i) do.call(paste, c(as.data.frame(i), sep = ':'))))
#[1] "1" "2" "5" "0" "1:2" "1:5" "2:5" "1:2:5"
I created a matrix in R
C<-matrix(c(0),nrow=6,ncol=6,byrow = FALSE)
Now I would like to replace the first column of the matrix with the value 1, the second and third column with standard normal random variables and the last three columns with the values of an other matrix.
C<-matrix(c(0),nrow=6,ncol=6,byrow = FALSE)
other.matrix<-matrix(runif(18), nrow = 6, ncol = 3)
C[,1]<-1
C[,3]<-rnorm(6)
C[,4:6]<-other.matrix
To access the rows and columns of matrices (and for that matter, data.frames) in R you can use [] brackets and i,j notation, where i is the row and j is the column. For example, the 3rd row and 2nd column of your matrix C can be addressed with
C[3,2]
#[1] 0
Use <- to assign new values to the rows/columns you have selected.
For the first three columns, you can use
C<-matrix(c(0),nrow=6,ncol=6,byrow = FALSE)
C[ ,1] <- 1; C[ ,2] <- rnorm(6); C[ ,3] <- rnorm(6)
Let's now say your other matrix is called D and looks like
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 0.6527716 0.81793644 0.67138209 0.3175264 0.1067119 0.5907180 0.4619992
[2,] 0.2268516 0.90893913 0.62917211 0.1768426 0.3659889 0.0339911 0.2322981
[3,] 0.9264116 0.81693835 0.59555163 0.6960895 0.1667125 0.6631861 0.9718530
[4,] 0.2613363 0.06515864 0.04971742 0.7277188 0.2580444 0.3718222 0.8028141
[5,] 0.2526979 0.49294947 0.97502566 0.7962410 0.8321882 0.2981480 0.7098733
[6,] 0.4245959 0.95951112 0.45632856 0.8227812 0.3542232 0.2680804 0.7042317
Now let's say you want columns 3,4, and 5 in from D as the last three columns in C, then you can simply just say
C[ ,4:6] <- D[ ,3:5]
And your result is
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 -1.76111875 0.4621061 0.67138209 0.3175264 0.1067119
[2,] 1 0.40036245 0.9054436 0.62917211 0.1768426 0.3659889
[3,] 1 -1.03238266 -0.6705829 0.59555163 0.6960895 0.1667125
[4,] 1 -0.47064774 0.3119684 0.04971742 0.7277188 0.2580444
[5,] 1 -0.01436411 -0.4688032 0.97502566 0.7962410 0.8321882
[6,] 1 -1.18711832 0.8227810 0.45632856 0.8227812 0.3542232
Just one thing to note is that this requires your number of rows to be the same between C and D.
I have a set of 80 samples, with 2 variables, each measured as triplicate:
sample var1a var1b var1c var2a var2b var2c
1 -169.784 -155.414 -146.555 -175.295 -159.534 -132.511
2 -180.577 -180.792 -178.192 -177.294 -171.809 -166.147
3 -178.605 -184.183 -177.672 -167.321 -168.572 -165.335
and so on. How do I apply functions like mean, sd, se etc. for each row for var1 and var2? Also, the dataset contains NAs. Thanks for bothering with such basic questions
What is your expected result when there are NAs? apply(df[-1], 1, mean) (or whatever function) will work, but it would give NA as a result for the row. If you can replace NA with 0 then you could do df[is.na(df)] <- 0 first, and then the apply function in order to get the results.
One approach could be to reshape your data set. Another one might be just apply a function over rows of a subset of the data frame.
So, for var2X you have:
apply(dat[5:7], 1, function(x){m <- mean(x); s <- sd(x); da <-c(m, s) })
[,1] [,2] [,3]
[1,] -155.78000 -171.750000 -167.076000
[2,] 21.63763 5.573734 1.632348
and for var1X:
apply(dat[2:4], 1, function(x){m <- mean(x); s <- sd(x); da <-c(m, s) })
[,1] [,2] [,3]
[1,] -157.25100 -179.853667 -180.153333
[2,] 11.72295 1.443055 3.520835