Reduce a matrix to a vector using tidyr in R [closed] - r

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have 10 100x100 matrices stored in a list (raw_data). I would like to convert by row each matrix in a column vector and bind all the columns in a single dataframe.
Basically, for each matrix A
A <- matrix(c(1:6), nrow = 2, ncol = 3)
A
[[1, 2, 3],
[4, 5, 6]]
and B
B <- matrix(c(7:12), nrow = 2, ncol = 3)
B
[[7, 8, 9],
[10, 11, 12]]
I would like to get a single dataframe:
A, B
1, 7
2, 8
3, 9
4, 10
5, 11
6, 12
This the solution I am using at the moment,
fun <- function(x) data.frame(as.vector(t(x), mode = "numeric")) # Tidyr
var_data <- lapply(raw_data[variables], fun) # Tidyr
var_df <- do.call(cbind, var_data) # Tidyr
names(var_df) <- variables
however it is not efficient and I would like to use something like tidyr instead. Is there an alternative option?
EDIT:
The list raw_data is the following:
raw_data = list(A,B)

How about,
as.data.frame(lapply(raw_data, c))
# X1.6 X7.12
#1 1 7
#2 2 8
#3 3 9
#4 4 10
#5 5 11
#6 6 12

We can use matrix
matrix(unlist(raw_data), ncol=2, dimnames= list(NULL, c("A", "B")))
# A B
#[1,] 1 7
#[2,] 2 8
#[3,] 3 9
#[4,] 4 10
#[5,] 5 11
#[6,] 6 12
Wrap it with as.data.frame if we need as a data.frame

Related

Aggregate rows in data.frame containing same values over different columns [duplicate]

This question already has answers here:
Aggregating regardless of the order of columns
(4 answers)
Closed 3 years ago.
The following works as expected:
m <- matrix (c(1, 2, 3,
1, 2, 4,
2, 1, 4,
2, 1, 4,
2, 3, 4,
2, 3, 6,
3, 2, 3,
3, 2, 2), byrow=TRUE, ncol=3)
df <- data.frame(m)
aggdf <- aggregate(df$X3, list(df$X1, df$X2), FUN=sum)
colnames(aggdf) <- c("A", "B", "value")
and results in:
A B value
1 2 1 8
2 1 2 7
3 3 2 5
4 2 3 10
But I would like to treat rows 1/2 and 3/4 as equal, not caring whether observation A is 1 and B is 2 or vice versa.
I also do not care about how the aggregation is sorting A/B in the final data.frame, so both of the following results would be fine:
A B value
1 2 1 15
2 3 2 15
A B value
1 1 2 15
2 2 3 15
How can that be achieved?
You need to get them in a consistent order. For just 2 columns, pmin and pmax work nicely:
df$A = with(df, pmin(X1, X2))
df$B = with(df, pmax(X1, X2))
aggregate(df$X3, df[c("A", "B")], FUN = sum)
# A B x
# 1 1 2 15
# 2 2 3 15
For more columns, use sort, as akrun recommends:
df[1:2] <- t(apply(df[1:2], 1, sort))
By changing 1:2 to all the key columns, this generalizes up easily.

Get matrix of minimum value from two equally sized matrix [duplicate]

This question already has answers here:
How can I take pairwise parallel maximum or minimum between two vectors?
(3 answers)
Closed 4 years ago.
I've looked everywhere but could find an answer.
I have to numerical matrix a
1 2 3
4 5 6
and b
3 1 4
5 2 1
and would like to get c equal to the minimum pairwise values of a and b
c
1 1 3
4 2 1
Thanks
You can use pmin, i.e.
pmin(m1, m2)
# [,1] [,2] [,3]
#[1,] 1 1 3
#[2,] 4 2 1
DATA:
m1 <- matrix(c(1, 2, 3, 4, 5, 6), ncol = 3, byrow = TRUE)
m2 <- matrix(c(3, 1, 4, 5, 2, 1), ncol = 3, byrow = TRUE)

Generating linear models for several columns in a dataframe at once [duplicate]

This question already has answers here:
Fitting a linear model with multiple LHS
(1 answer)
Fast pairwise simple linear regression between variables in a data frame
(1 answer)
Closed 4 years ago.
I have the following dataframe:
Index <- seq.int(1:10)
A <- c(5, 5, 3, 4, 3, 3, 2, 2, 4, 3)
B <- c(10, 11, 12, 12, 12, 11, 13, 13, 14, 13)
C <- c(7, 6, 7, 7, 6, 5, 6, 5, 5, 4)
df <- data.frame(Index, A, B, C)
> df
Index A B C
[1,] 1 5 10 7
[2,] 2 5 11 6
[3,] 3 3 12 7
[4,] 4 4 12 7
[5,] 5 3 12 6
[6,] 6 3 11 5
[7,] 7 2 13 6
[8,] 8 2 13 5
[9,] 9 4 14 5
[10,] 10 3 13 4
I would like to generate the following three linear models:
lm(df$A ~ df$Index)
lm(df$B ~ df$Index)
lm(df$C ~ df$Index)
Is there a way to do this quickly and efficiently in one step (possibly using the lapply function)? My actual data frame has many more rows and columns. Thanks!
Try
df <- data.frame(Index, A, B, C)
lm(cbind(A, B, C) ~ Index, data = df)
#Call:
#lm(formula = cbind(A, B, C) ~ Index, data = df)
#Coefficients:
# A B C
#(Intercept) 4.6000 10.2667 7.4000
#Index -0.2182 0.3333 -0.2909
Note that df must be a dataframe.
You can also use a tidyverse approach like this:
library(tidyverse)
df %>%
gather(Variables, Value, A:C) %>%
split(.$Variables) %>%
map(~ lm(Value~Index, data = .)) %>%
map(summary)

Multiply each element of a special column of a data frame with the corresponding elements of other columns of the data frame

I have a data frame df with four columns; three integer columns and a special column containing a list:
df <- data.frame(w= 1:3, x=3:5, y=6:8, z = I(list(1:2, 1:3, 1:4)))
> df
w x y z
1 1 3 6 1, 2
2 2 4 7 1, 2, 3
3 3 5 8 1, 2, 3, 4
>class(df$z)
[1] "AsIs"
I want to transform each element of the column df["z"] by separately multiplying it with the corresponding element (same row number) of each of the other columns (df["w"], df["x"], df["y"]) of the same data frame df.
I have found the possibility of using Map("*", df$z, df$x), but it can only perform the required multiplication with one other column at a time. My data set is too large to let me perform the multiplication in such small steps.
> Map("*", df$z, df$x)
[[1]]
[1] 3 6
[[2]]
[1] 4 8 12
[[3]]
[1] 5 10 15 20
Can anyone please provide a hint on how to multiply df["z"] with each of the other columns at once while preserving the data frame structure?
I expect the output to be a data frame df1 with column names w,x,y.
>df1
w x y
1 2 3 6 6 12
2 4 6 4 8 12 7 14 21
3 6 9 12 5 10 15 20 8 16 24 32
Thank you.
We can use transmute_at
library(tidyverse)
df %>%
transmute_at(vars(w, x, y), funs(map2(z, ., `*`)))
# w x y
#1 1, 2 3, 6 6, 12
#2 2, 4, 6 4, 8, 12 7, 14, 21
#3 3, 6, 9, 12 5, 10, 15, 20 8, 16, 24, 32
Or as #Ryan mentioned if there are more columns and the multiplier list column is single, we can use one_of within transmute_at to select other columns except the 'z'
df %>%
transmute_at(vars(-one_of('z')), funs(map2(z, .,`*`)))

Cross merge two vectors [duplicate]

This question already has answers here:
How to merge 2 vectors alternating indexes?
(6 answers)
Closed 5 years ago.
How to crossly merge two vectors in R?
For example, from c(1,2,3,4) and c(5,6,7,8) to construct c(1,5,2,6,3,7,4,8).
a <- c(1, 2, 3, 4)
b <- c(5, 6, 7, 8)
ab <- as.vector(matrix(c(a, b), nrow = 2, byrow = TRUE))
ab
[1] 1 5 2 6 3 7 4 8
Similar to ycw's method, you could use rbind to construct the matrix and then form a vector with c:
c(rbind(a, b))
[1] 1 5 2 6 3 7 4 8
data
a <- 1:4
b <- 5:8
Another option that works also well when the length of the vectors are not the same would be to order by the concatenated sequence of both vectors
c(a,b)[order(c(seq_along(a), seq_along(b)))]
#[1] 1 5 2 6 3 7 4 8
data
a <- c(1, 2, 3, 4)
b <- c(5, 6, 7, 8)

Resources