For following argument
x <- c(1,3,4,24,1,2,2,2,1,3,3,1,1,0,8)
A <- matrix(x,nrow = 5)
n <- ncol(A)
t(A)
meancol <- colMeans(A)
meancol
t(t(meancol))
I am writing to ask why for t(A), I only need put t() to get what I want, but for meancol,I need to put t(t()) to get the results.
Notice that the output of meancol <- colMeans(A) isn't a matrix, then the function transpose interprets it as a vector.
From the Details of the function t() we have:
Details This is a generic function for which methods can be written.
The description here applies to the default and "data.frame" methods.
A data frame is first coerced to a matrix: see as.matrix. When x is a
vector, it is treated as a column, i.e., the result is a 1-row matrix.
The vector is read as a 1-column matrix, therefore the result is a 1-row matrix.
Related
I want to create a function and use sapply to pass a number of input variables through it. The trick: the "variables" are actually vectors. I include an example below, where I would like to transpose the vectors a, b, and d, without having to manually write each command individually. I include the x <- part, while leaving it blank, because this is one of the main points of my confusion. Were I creating a normal function, I would simply create a vector of all the variables I want to pass through form5. However, if I create a vector from vectors, I'll just have a longer vector. So to be clear, I'd like sapply to return a matrix or dataframe with all 3 transposed vectors.
a <- c(1:10)
b <- c(11:20)
d <- c(21:30)
X <-
form5 <- function(x){
t(x)
}
sapply(x, form5)
I have four matrices which contain positive and negative values. Now I would like to convert all negative values for each matrix to NA. The matrices are called Main_mean, Inn_mean, Isar_mean and Danube_mean.
For a single matrix this would be quite easy:
Main_mean[Main_mean<=0] <- NA.
But how should it look like in a loop?
Get the matrix in a list and apply the function to each one using lapply :
list_obj <- mget(ls(pattern = '_mean$'))
#Or make a list individually
#list_obj <- mget(c('Main_mean', 'Danube_mean', 'Inn_mean', 'Isar_mean'))
result <- lapply(list_obj, function(x) {x[x<=0] <- NA;x})
To replace the original objects you can use list2env.
list2env(result, .GlobalEnv)
I have a function f(list,t) where the first argument is a list and the second one t is a number. I wanna apply f to columns of a matrix M and elements of a vector T respectively. Hence, if columns of M are (M_1,M_2,...,M_k) and T = (t_1,t_2,...,t_k), I want to get the following :
f(M_1,t_1), f(M_2,t_2), ..., f(M_k,t_k).
Is there an efficient way doing so without using for loop?
For example if
f <- function(list,x) {x %in% list}
M <- matrix(1:12,4,3)
T <- c(1,2,10)
I expect to get
TRUE FALSE TRUE
The following line applies f on each column of M and each element of T
apply(M,2,f,T)
But what I need is just the diagonal of this output, so I want a way to avoid extra computations.
You can also use sapply using the number of columns in the matrix. Later, we use any to return True (if any) value from each column
Tr <- c(1,2,10)
sapply(seq(ncol(M)), function(x) any(f(M[,x], Tr)))
[1] TRUE FALSE TRUE
Convert your matrix to a data frame and then use the map2 function from the purrr package:
library(tidyr)
df <- as.data.frame(M)
unlist(map2(df, t, f))
Also it is a terrible idea to name a variable T (or F) as that can cause a ton of problems with logical terms.
mapply(f,as.data.frame(M),T)
as.data.frame is needed to convert M to the list of the matrix columns, and mapply applies f to the produced list and vector T in a pairwise fashion.
df is a frequency table, where the values in a were reported as many times as recorded in column x,y,z. I'm trying to convert the frequency table to the original data, so I use the rep() function.
How do I loop the rep() function to give me the original data for x, y, z without having to repeat the function several times like I did below?
Also, can I input the result into a data frame, bearing in mind that the output will have different column lengths:
a <- (1:10)
x <- (6:15)
y <- (11:20)
z <- (16:25)
df <- data.frame(a,x,y,z)
df
rep(df[,1], df[,2])
rep(df[,1], df[,3])
rep(df[,1], df[,4])
If you don't want to repeat the for loop, you can always try using an apply function. Note that you cannot store it in a data.frame because the objects are of different lengths, but you could store it in a list and access the elements in a similar way to a data.frame. Something like this works:
df2<-sapply(df[,2:4],function(x) rep(df[,1],x))
What this sapply function is saying is for each column in df[,2:4], apply the rep(df[,1],x) function to it where x is one of your columns ( df[,2], df[,3], or df[,4]).
The below code just makes sure the apply function is giving the same result as your original way.
identical(df2$x,rep(df[,1], df[,2]))
[1] TRUE
identical(df2$y,rep(df[,1], df[,3]))
[1] TRUE
identical(df2$z,rep(df[,1], df[,4]))
[1] TRUE
EDIT:
If you want it as a data.frame object you can do this:
res<-as.data.frame(sapply(df2, '[', seq(max(sapply(df2, length)))))
Note this introduces NAs into your data.frame so be careful!
I have a matrix and a function that takes a vector and returns a matrix. I want to apply the function to all rows of the matrix and rbind all results together. For example
mat <- matrix(1:6, ncol=2)
f <- function (x) cbind(1:sum(x), sum(x):1)
do.call(rbind, apply(mat, 1, f))
This works perfectly since the returned matrices have different numbers of rows so apply returns a list. But if they happen to have the same numbers of rows this does not work anymore:
mat <- f(3)
apply(mat, 1, f)
apply returns a matrix from which I cannot get the result I want. Is it possible to force apply to return a list or is there another solution?
This is why I love the plyr package. It has a number of --ply functions that all work in the same way. The first letter corresponds to what you have as input and the second method corresponds to what you have as output (l for lists, a for arrays, d for data frames).
So the alply() function works similar to apply() but always returns a list:
alply(mat, 1, f)
You have to split matrix mat before applying function f.
list_result <- lapply(split(mat,seq(NROW(mat))),f)
matrix_result <- do.call(rbind,list_result)