I have found read.csv("file.csv")$V1 that may help to split exported table into columns but my data is organised in a row-by-row fashion, so I would like to record elements to vector sequentially from element[1][1] ->...->element[n][n]. Any thoughts how it could be accomplished in R?
Update:
Once imported mydata looks like:
dat <- matrix(1:27, nrow = 3)
dat
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] 1 4 7 10 13 16 19 22 25
[2,] 2 5 8 11 14 17 20 23 26
[3,] 3 6 9 12 15 18 21 24 27
Desired output would be vector: c(1, 2, 3, 4, 5, 6, 7.....)
With the code I provided a simple solution could be to extract simply the row, but it looks too much easy maybe I missed something.
new_dat <- dat[1, ]
new_dat
[1] 1 4 7 10 13 16 19 22 25
Edit
My solution works well but it is not efficient. Here I have an improved loop versions so you can store objects separately in only one command.
First define elements that will be the name of the objects:
val <- c(1:3)
nam <- "new_dat_"
and then extract all elements with the loop.
for(i in 1:nrow(dat)){ assign(paste(nam, val, sep = "")[i], dat[i, ]) }
after that use ls() and you should see 3 elements named new_dat_1","new_dat_2", "new_dat_3" "val" each of them contains one row of your dat. This solution can be very helpful if you have to extract several rows and not just one and lead to this output:
new_dat_3
[1] 3 6 9 12 15 18 21 24 27
new_dat_1
[1] 1 4 7 10 13 16 19 22 25
new_dat_2
[1] 2 5 8 11 14 17 20 23 26
Related
In R, I have a matrix of...
data1 <- c(9,8,7,6,5,4,3,2,1,10,11,12,13,14,15)
matrix_1 <- matrix(data1,nrow=5,ncol=3,byrow=T)
Now that should create the matrix
[,1] [,2] [,3]
[1,] 9 8 7
[2,] 6 5 4
[3,] 3 2 1
[4,] 10 11 12
[5,] 13 14 15
My goal is to create a 6x4 matrix with that exact matrix for the first 5 rows and 3 columns, then the remaining row and column are sums of the respective row or column, then the single extra spot in the bottom right corner is the total sum of the entire first matrix (matrix_1).
I assume I need to use for loops, but I can't figure out how to get it. Thanks.
I tried messing with the for loop a bit, but I'm stuck on what to sum for that second matrix as well as how to cut the loop at the right point.
Base R has the addmargins() convenience function for this. The default returns the sum of all margins of a matrix or array.
addmargins(matrix_1)
Sum
9 8 7 24
6 5 4 15
3 2 1 6
10 11 12 33
13 14 15 42
Sum 41 40 39 120
R has an apply family (apply, sapply, lapply etc.) that allows you to do stuff without using a for loop.
Here, row sum and column sum are calculated using apply, where 1 in apply(matrix_1, 1, sum) specifies row-wise operation, and 2 specifies column-wise operation. Then rbind and cbind the results to output a 6 x 4 matrix.
rbind(
cbind(matrix_1, apply(matrix_1, 1, sum)),
c(apply(matrix_1, 2, sum), sum(matrix_1))
)
However, in your case, you don't really need to use apply. You can use rowSums and colSums in base R to do the job.
rbind(
cbind(matrix_1, rowSums(matrix_1)),
c(colSums(matrix_1), sum(matrix_1))
)
Output
[,1] [,2] [,3] [,4]
[1,] 9 8 7 24
[2,] 6 5 4 15
[3,] 3 2 1 6
[4,] 10 11 12 33
[5,] 13 14 15 42
[6,] 41 40 39 120
I would like to index a vector inside a list within a list, and generate a new dataframe that contains that specific vector in each of the lists in every row. I was previously considering using a for loop to do so
a = list(odds = c(1,3,5,7), evens = c(2,4,6,8), name = "name1")
b = list(odds = c(9,11,13,15), evens = c(10,12,14,16), name = "name2")
c = list(odds = c(17,19,21,23), evens = c(18,20,22,24), name = "name3")
d = list(a,b,c)
output = data.frame()
for (i in 1:length(d)) {
output <- rbind(output, d[[i]]$odds)
}
The expected output is as such
# X1 X3 X5 X7
# 1 1 3 5 7
# 2 9 11 13 15
# 3 17 19 21 23
However, as I perpetually require to do such indexing when I handle data, I was wondering if there was a less convoluted method of doing this. Is there perhaps a cleaner method using lapply and rbind functions to avoid looping? I could not figure out how to index the vector required.
Apologies if the question is poorly formatted, this is my first time posting on a coding forum.
You can use :
res <- data.frame(t(sapply(d, `[[`, 'odds')))
# X1 X2 X3 X4
#1 1 3 5 7
#2 9 11 13 15
#3 17 19 21 23
We can use
library(dplyr)
library(purrr)
d %>%
transpose %>%
pluck('odds') %>%
invoke(rbind, .)
# [,1] [,2] [,3] [,4]
#[1,] 1 3 5 7
#[2,] 9 11 13 15
#[3,] 17 19 21 23
This can also be used, albeit very similar to the one posted by dear #akrun. map family of functions also accept integer or character vector in place of anonymous function or formula. In that case it serves as an extractor function by index(integer) or name (character). Then it calls internally to pluck as specified by #akrun's solution. You can verify it by as_mapper("odds").
library(purrr)
# We use big bang operator to splice the list of arguments and then
# use exec to apply `rbind` function to the spliced list.
exec(rbind, !!!map(d, "odds"))
[,1] [,2] [,3] [,4]
[1,] 1 3 5 7
[2,] 9 11 13 15
[3,] 17 19 21 23
Another base R option using simplify2array
> t(do.call(cbind, simplify2array(d)["odds", ]))
[,1] [,2] [,3] [,4]
[1,] 1 3 5 7
[2,] 9 11 13 15
[3,] 17 19 21 23
How I can combine the values of the columns? Like this:
Expected output:
Another option using rbind.
d <- seq(1, 27)
m <- matrix(d, nrow=3, byrow=TRUE)
Then m would look as follows (mimicking your input data):
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
[1,] 1 2 3 4 5 6 7 8 9
[2,] 10 11 12 13 14 15 16 17 18
[3,] 19 20 21 22 23 24 25 26 27
Then you can call rbind on chunks of your input; for bigger matrices you might want to do this in a for-loop:
mnew = data.frame(rbind(m[, 1:3], m[ ,4:6], m[,7:9]))
names(mnew) <- c('V1', 'V2', 'V3')
That yields the desired output:
V1 V2 V3
1 1 2 3
2 10 11 12
3 19 20 21
4 4 5 6
5 13 14 15
6 22 23 24
7 7 8 9
8 16 17 18
9 25 26 27
first you must say which columns you want to combine but you can do it like this considering that dat is the name of your dataframe
dt <- data.frame(c(dat$V1,dat$V4,dat$V7),c(dat$V2,dat$V5,dat$V8),c(dat$V3,dat$V6,dat$V9))
then rename your columns using names(dt) <- c("V1","V2","V3")
Let's say your basic dataframe is named df1
Using rbind, as Orhan already said, you had to split your dataframe and rename the columns:
a <- df1[1:3]
names(a) <- c("V1","V2", "V3")
b <- df1[4:6]
names(b) <- c("V1","V2", "V3")
c <- df1[7:9]
names(c) <- c("V1","V2", "V3")
df2<- rbind(a,b,c)
This could be easily be performed by changing df to á matrix and then using rbind
df <- as.matrix(df)
df <- rbind(df[,1:3],df[,4:6],df[,7:9])
Then you have the option of converting it back to data.frame using as.data.frame()
This question already has answers here:
Mean of each element of a list of matrices
(3 answers)
Closed 6 years ago.
I have a list of matrices:
.list <- list(matrix(1:25, ncol = 5), matrix(11:35, ncol = 5))
I would like to use the Reduce method to find the element-by-element means of the matrices in the list.
In other words, I am looking for the following result:
res = matrix(6:30, ncol = 5)
I tried the following:
res = Reduce(mean, .list)
but I get an error:
Error in mean.default(init, x[[i]]) :
'trim' must be numeric of length one
Note that an element of a matrix can be NA.
Any help would be appreciated! Thank you!!
I just realized that this could be achieved the following way (using the Reduce function):
tmp = Reduce('+', .list)
result = tmp/length(.list)
This is probably easier to solve via an array, rather than a list, as R has some inbuilt, vectorised approaches to this problem.
To get an array from .list, unlist it and supply the relevant dimensions (which could be automated by looking up the dim() of .list[[1]] and length(.list):
arr <- array(unlist(.list), dim = c(5,5,2))
Then, the desired result is obtained via rowMeans() (yes, really!)
rowMeans(arr, dim = 2)
R> rowMeans(arr, dim = 2)
[,1] [,2] [,3] [,4] [,5]
[1,] 6 11 16 21 26
[2,] 7 12 17 22 27
[3,] 8 13 18 23 28
[4,] 9 14 19 24 29
[5,] 10 15 20 25 30
The na.rm argument handles the NA case too:
R> rowMeans(arr, dim = 2, na.rm = TRUE)
[,1] [,2] [,3] [,4] [,5]
[1,] 6 11 16 21 26
[2,] 7 12 17 22 27
[3,] 8 13 18 23 28
[4,] 9 14 19 24 29
[5,] 10 15 20 25 30
A slower way is to use apply(), which may be more instructive as to what rowMeans() is doing:
R> apply(arr, 1:2, mean, na.rm = TRUE)
[,1] [,2] [,3] [,4] [,5]
[1,] 6 11 16 21 26
[2,] 7 12 17 22 27
[3,] 8 13 18 23 28
[4,] 9 14 19 24 29
[5,] 10 15 20 25 30
i.e applying the mean function, grouping the data by the row and column dimensions. Think of the array as a box, with the height of the box being the third dimension. This box consists of little cubes, like a rubic cube. We want the mean of the little cubes stacked up above each row and column combination; the mean of the little cubes stacked above (1,1), and so on. This is what the apply() and rowMeans() functions do for you, if you treat the multiple matrices in a list as an array.
Here is one way with mapply.
matrix(do.call(mapply, c(function(...) mean(unlist(list(...))), .list)), ncol=5)
As a side note, .list isn't the best way to use a keyword as a variable name. In R, the period prefix means something like "meta-variable", and these variables won't show up when you call ls(). You could do list. or the easier to read list_.
This question already has answers here:
Get the row and column name of the minimum element of a matrix
(2 answers)
Closed 5 years ago.
I wish to find the maximum element-value of a matrix and it's location (in row and column id in the matrix).
I am using the following function to return the row and column of the matrix.
This seems like a bad hack -- it's the sort of thing where i'm probably missing a native method. Is there a better / more R way?
Here's my function:
matxMax <- function(mtx)
{
colmn <- which(mtx == max(mtx)) %/% nrow(mtx) + 1
row <- which(mtx == max(mtx)) %% nrow(mtx)
return( matrix(c(row, colmn), 1))
}
I use is as follows:
mm <- matrix(rnorm(100), 10, 10)
maxCords <- matxMax(mm)
mm[maxCords]
You could do
## Some data
set.seed(123)
mm <- matrix(rbinom(40, 20, 0.5), 8, 5)
mm
# [,1] [,2] [,3] [,4] [,5]
# [1,] 9 10 8 11 11
# [2,] 12 10 6 11 12
# [3,] 9 14 9 10 6
# [4,] 13 10 14 11 10
# [5,] 13 11 13 9 12
# [6,] 6 10 11 8 8
# [7,] 10 7 11 14 9
# [8,] 13 13 16 13 8
which(mm == max(mm), arr.ind = TRUE)
# row col
# [1,] 8 3