Convert from n x m matrix to long matrix in R [duplicate] - r

This question already has answers here:
Create dataframe from a matrix
(6 answers)
Closed 1 year ago.
Note: This is not a graph question.
I have an n x m matrix:
> m = matrix(1:6,2,3)
> m
a b c
d 1 2 3
e 4 5 6
I would like to convert this to a long matrix:
> m.l
a d 1
a e 4
b d 2
b e 5
c d 3
c e 6
Obviously nested for loops would work but I know there are a lot of nice tools for reshaping matrixes in R. So far, I have only found literature on converting from long or wide matrixes to an n x m matrix and not the other way around. Am I missing something obvious? How can I do this conversion?
Thank you!

If you need a single column matrix
matrix(m, dimnames=list(t(outer(colnames(m), rownames(m), FUN=paste)), NULL))
# [,1]
#a d 1
#a e 4
#b d 2
#b e 5
#c d 3
#c e 6
For a data.frame output, you can use melt from reshape2
library(reshape2)
melt(m)

Related

Randomize vector order with maximum variance

I have a vector that looks something like this.
v <- as.data.frame(list(v=(c("a","b","c",'d','e'))))
v
v
1 a
2 b
3 c
4 d
5 e
My vector has 5 different values. This means I can make 120 permutations of my vector.
Here are some examples of permutations
v v2 v3
1 a a a
2 b b c
3 c c b
4 d e d
5 e d e
I would like to create only create 10 different vectors out of the 120 possible ones, but I would like to select the combination that should maximise their covariance. Any idea how I could do this?
thanks a lot in advance for your help

cbind named vectors in R by name

I have two named vectors similar to these ones:
x <- c(1:5)
names(x) <- c("a","b","c","d","e")
t <- c(6:10)
names(t) <- c("e","d","c","b","a")
I would like to combine them so to get the following outcome:
x t
a 1 10
b 2 9
c 3 8
d 4 7
e 5 6
Unfortunately when I run cbind(x,t) the result just combines them in the order they are disregarding the names of t and only keeping those of x. Giving the following result:
x t
a 1 6
b 2 7
c 3 8
d 4 9
e 5 10
I'm pretty sure there must be an easy solution, but I cannot find it. As this passage is part of a long and tedious loop (and the vectors I'm working with are much longer), it is important to have the least convoluted and quicker to compute options.
We can use the names of 'x' to change the order the 't' elements and cbind with 'x'
cbind(x, t = t[names(x)])
# x t
#a 1 10
#b 2 9
#c 3 8
#d 4 7
#e 5 6

convert values of a column based on another dataframe in R [duplicate]

This question already has answers here:
How to join (merge) data frames (inner, outer, left, right)
(13 answers)
Closed 6 years ago.
I have a data.frame
df1=data.frame(f=LETTERS[1:4],v=c(1:4))
f v
1 A 1
2 B 2
3 C 3
4 D 4
The first column is a list of factors, in which I have another data frame that houses these values, which are also factors
df2=data.frame(f=LETTERS[1:7],f2=letters[26:20])
f f2
1 A z
2 B y
3 C x
4 D w
5 E v
6 F u
I am wondering how to write a function so that I can alter the values from the first column of df1 to what they map to from df2. I would like to get:
f v
1 z 1
2 y 2
3 x 3
4 w 4
I tried a for loop with no success. Ant suggestions is greatly appreciated
Note: this is a simplified example of my work. A merge would add too many columns to work with and I don't think the extra memory storage would be very useful
We can use match
df1$f <- df2$f2[match(df1$f, df2$f)]
df1
# f v
#1 z 1
#2 y 2
#3 x 3
#4 w 4
You can use merge
merge(df1,df2,by = "f")[,c(1,3,2)]
f f2 v
1 A z 1
2 B y 2
3 C x 3
4 D w 4
library(dplyr)
left_join(df1,df2)
You could try using the merge function to merge the two tables, then specify which columns you want to keep.
For example:
df1 <- data.frame(f=LETTERS[1:4],v=c(1:4))
df2 <- data.frame(f=LETTERS[1:7],f2=letters[26:20])
merge(df1, df2, by.x = "f")[,c("f2", "v")]
f2 v
1 z 1
2 y 2
3 x 3
4 w 4

create all possible permutations of two vectors in R [duplicate]

This question already has answers here:
Generate all possible permutations (or n-tuples)
(2 answers)
Closed 9 years ago.
I have two vectors like this:
f1=c('a','b','c','d')
e1=c('e','f','g')
There is 4^3 different permutations of them. I need to create all of possible permutations of them in R softeware.for example;
(1):
a e
a f
a g
(2):
a e
a f
b g
...
Moreover, my real data are very huge and I need speed codes.
It sounds like you are looking for expand.grid.
> expand.grid(f1, e1)
Var1 Var2
1 a e
2 b e
3 c e
4 d e
5 a f
6 b f
7 c f
8 d f
9 a g
10 b g
11 c g
12 d g
I don't know what "speed codes" are, so I'm not sure I can help from that aspect.

Working with long data format in R

Good day,
d <- c(1,1,1,2,2,2,3,3,3)
e <- c(5,6,7,5,6,7,5,6,7)
f <- c(0,0,1,0,1,0,0,0,1)
df <- data.frame(d,e,f)
I have data the looks like the above. What I need to do is for each unique element of d find the first non-zero value in f, and find the corresponding value in e. To be specific, I want another vector g so it looks like this:
d <- c(1,1,1,2,2,2,3,3,3)
e <- c(5,6,7,5,6,7,5,6,7)
f <- c(0,0,1,0,1,0,0,0,1)
g <- c(7,7,7,6,6,6,7,7,7)
df <- data.frame(d,e,f,g)
Suggestions to do this easily? I thought I could use split(), but I am having trouble using which() after the split. I can use ave like this:
foo <- function(x){which(x>0)[1]}
df$t <- ave(df$f,df$d,FUN=foo)
But I am having trouble finding the value of e. Any help is appreciated.
Someone else can provide a base R solution, but here's a way to do this using plyr:
> ddply(df,.(d),transform,g = head(e[f != 0],1))
d e f g
1 1 5 0 7
2 1 6 0 7
3 1 7 1 7
4 2 5 0 6
5 2 6 1 6
6 2 7 0 6
7 3 5 0 7
8 3 6 0 7
9 3 7 1 7
Note that I took your note about the "first nonzero element" literally, even though your example data only had a single unique nonzero element in the column (by group).
here's a way in base R
g <- inverse.rle(list(lengths=rle(d)$lengths, values=e[f != 0]))

Resources