How to convert the table() to a data.frame? - r

I have a 6x6 matrix:
M = matrix(0,nrow = 6, ncol = 6);
for(i in 1:6)
for(j in 1:6)
M[i,j]<- i+j
> M
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 2 3 4 5 6 7
[2,] 3 4 5 6 7 8
[3,] 4 5 6 7 8 9
[4,] 5 6 7 8 9 10
[5,] 6 7 8 9 10 11
[6,] 7 8 9 10 11 12
I am using table() function to build a contingency table of the counts at each combination of factor levels.
table(M)
output:
> table(M)
M
2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 5 4 3 2 1
Now I want to convert the table(M) to a data.frame using following:
pmfY <- data.frame(table(M))
But the pmfY$M changes to the follwong:
> pmfY$M
[1] 1 2 3 4 5 6 7 8 9 10 11
I am expecting pmfY$M to be the following vector in data frame.
2 3 4 5 6 7 8 9 10 11 12
Why pmfY$M is changed when converting table(M) to data frame and how to fix it?

Related

how to assign the size of 2-D matrix to two new variable in r?

This is what I know in Matlab and want do same in r programming
A=[1 2 3;4 5 6; 7 8 9];
A =
1 2 3
4 5 6
7 8 9
[m,n]=size(A)
m=3
n=3
so here I have two distinct variables to which the dimension or size of 2D matrix is assigned automatically
> x<-c(1:10)
> x
[1] 1 2 3 4 5 6 7 8 9 10
> A=matrix(0,10,10)
> A=Toeplitz(x,c(x[1],rev(x[-1])))
> A
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 10 9 8 7 6 5 4 3 2
[2,] 2 1 10 9 8 7 6 5 4 3
[3,] 3 2 1 10 9 8 7 6 5 4
[4,] 4 3 2 1 10 9 8 7 6 5
[5,] 5 4 3 2 1 10 9 8 7 6
[6,] 6 5 4 3 2 1 10 9 8 7
[7,] 7 6 5 4 3 2 1 10 9 8
[8,] 8 7 6 5 4 3 2 1 10 9
[9,] 9 8 7 6 5 4 3 2 1 10
[10,] 10 9 8 7 6 5 4 3 2 1
> n=size(A)
> n
[1] 10 10
>[ m,n]=size(A)
this is not working so is there any way to assign the size of the 2Dmatrix to two distinct variable m and n in r.I am learning r programming and need help

Constructing a randomised matrix with no duplicates but fixed partial input

I´m facing a problem with constructing a randomised matrix where I partially already have values (that need to stay fixed - so no further randomisation there).
Lets see:
matrix should end up being 10 by 10
n <- 10
I do want my first rows to be the data I enter. e.g:
row1<- c(1,4,7,6,5,3,2,8,9,10)
row2<- c(10,7,3,2,1,4,5,9,8,6)
row3<- c(9,2,4,3,8,7,10,1,6,5)
To bild a matrix with 10 rows (and 10 columns) I combined those rows with samples (no replace because I want each number to be unique in each row).
first.rows<-rbind(row1,row2,row3,sample(n,n,replace=F),sample(n,n,replace=F),sample(n,n,replace=F),sample(n,n,replace=F),sample(n,n,replace=F),sample(n,n,replace=F),sample(n,n,replace=F))
output:
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
row1 1 4 7 6 5 3 2 8 9 10
row2 10 7 3 2 1 4 5 9 8 6
row3 9 2 4 3 8 7 10 1 6 5
6 1 5 4 2 10 3 8 7 9
2 5 7 8 9 6 1 3 4 10
10 6 4 1 8 3 7 2 5 9
8 5 3 2 4 1 10 7 6 9
10 7 9 6 8 2 5 4 3 1
1 10 8 4 7 3 5 2 6 9
2 1 10 4 8 9 3 6 5 7
So far so good..
However now I have the problem that there is no control for unique numbers in the columns. This is what I would need though. I get that this the case because I used rbind (and therefore only the function of no duplicates only works for the rows). But I do not know how else to approach this problem. The rows 1-3 should stay exactly as they are now.
Any ideas?
I think my previous solution Fixed values not repeated over column and row can be modified to work. You need a solver, but instead of starting with a empty grid, it starts with a pre-filled matrix:
# x is your matrix, "not filled" values should be NA
# x is a square matrix with dimension n (big n will take longer to converge)
backtrack = function(x){
n = ncol(x)
stopifnot(ncol(x)==nrow(x))
cells = list()
k = 1
for (i in 1:n){
for (j in 1:n){
if (is.na(x[i, j]))
cells[[k]] = sample(1:n)
else
cells[[k]] = NULL
k = k + 1
}
}
i = 0
while (i < n*n){
if (is.null(cells[[i+1]])){
i=i+1
next
}
candidates = cells[[i + 1]]
idx = sample(1:length(candidates), 1)
val = candidates[idx]
if (length(candidates) == 0){
cells[[i + 1]] = sample(1:n)
i = i - 1
x[as.integer(i/n) + 1, i %% n + 1] = NA
}
else {
rr = as.integer(i/n) + 1
cc = i %% n + 1
if ((val %in% x[rr, ]) || (val %in% x[, cc])){
candidates = candidates[-idx]
cells[[i + 1]] = candidates
}
else{
x[as.integer(i/n) + 1, i %% n + 1] = val
candidates = candidates[-idx]
cells[[i + 1]] = candidates
i = i + 1
}
}
}
x
}
Empty initial matrix
set.seed(1)
x = backtrack(matrix(NA, nrow = 10, ncol = 10))
print(x)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 8 10 4 6 9 7 1 2 3 5
[2,] 5 6 9 8 1 10 4 3 2 7
[3,] 10 7 1 2 8 9 5 4 6 3
[4,] 3 9 8 10 6 5 7 1 4 2
[5,] 9 1 6 4 7 3 2 5 10 8
[6,] 1 4 10 3 2 6 8 7 5 9
[7,] 2 8 5 9 10 1 3 6 7 4
[8,] 6 5 2 7 3 4 10 9 8 1
[9,] 4 3 7 1 5 2 6 8 9 10
[10,] 7 2 3 5 4 8 9 10 1 6
Pre-filled initial matrix
m = matrix(NA, ncol = 10, nrow = 10)
m[1, ] = c(1,4,7,6,5,3,2,8,9,10)
m[2, ] = c(10,7,3,2,1,4,5,9,8,6)
m[3, ] = c(9,2,4,3,8,7,10,1,6,5)
x = backtrack(m)
print(x)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 1 4 7 6 5 3 2 8 9 10
[2,] 10 7 3 2 1 4 5 9 8 6
[3,] 9 2 4 3 8 7 10 1 6 5
[4,] 5 9 6 8 3 2 4 7 10 1
[5,] 7 1 5 10 9 6 3 2 4 8
[6,] 2 5 8 1 10 9 6 3 7 4
[7,] 6 3 1 4 7 5 8 10 2 9
[8,] 8 10 9 5 4 1 7 6 3 2
[9,] 3 6 10 9 2 8 1 4 5 7
[10,] 4 8 2 7 6 10 9 5 1 3
NOTE: I didn't tested it for bugs.

How can I find repeated values/ data points and their index in 2D matrix of a dataframe in R?

For example suppose I have matrix A
x y z f
1 1 2 A 1005
2 2 4 B 1002
3 3 2 B 1001
4 4 8 C 1001
5 5 10 D 1004
6 6 12 D 1004
7 7 11 E 1005
8 8 14 E 1003
From this matrix I want to find the repeated values like 1001, 1005, D, 2 (in third column) and I also want to find their index (which row, or which position).
I am new to R!
Obviously it is possible to do with simple searching element by element by using a for loop, but I want to know, is there any function available in R for this kind of problem.
Furthermore, I tried using duplicated and unique, both functions are giving me the duplicated row number or column number, they are also giving me how many of them were repeated, but I can not search for whole matrix using both of them!
You can write a rather simple function to get this information. Though note that this solution works with a matrix. It does not work with a data.frame. A similar function could be written for a data.frame using the fact that the data.frame data structure is a subset of a list.
# example data
set.seed(234)
m <- matrix(sample(1:10, size=100, replace=T), 10)
find_matches <- function(mat, value) {
nr <- nrow(mat)
val_match <- which(mat == value)
out <- matrix(NA, nrow= length(val_match), ncol= 2)
out[,2] <- floor(val_match / nr) + 1
out[,1] <- val_match %% nr
return(out)
}
R> m
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 8 6 6 7 6 7 4 10 6 9
[2,] 8 6 6 3 10 4 5 4 6 9
[3,] 1 6 9 2 9 2 3 6 4 2
[4,] 8 6 7 8 3 9 9 4 9 2
[5,] 1 1 5 6 7 1 5 1 10 6
[6,] 7 5 4 7 8 2 4 4 7 10
[7,] 10 4 7 8 3 1 8 6 3 4
[8,] 8 8 2 2 7 5 6 4 10 4
[9,] 10 2 9 6 6 9 7 2 4 7
[10,] 3 9 9 4 2 7 7 2 9 6
R> find_matches(m, 8)
[,1] [,2]
[1,] 1 1
[2,] 2 1
[3,] 4 1
[4,] 8 1
[5,] 8 2
[6,] 4 4
[7,] 7 4
[8,] 6 5
[9,] 7 7
In this function, the row index is output in column 1 and the column index is output in column 2

Switching the first element with the last one in a loop

Is there a function in R which switches the first element with the last one in a vector? I have a for loop which need that reordering. From:
months = seq(1:12)
[1] 1 2 3 4 5 6 7 8 9 10 11 12
I would like to have:
[1] 12 1 2 3 4 5 6 7 8 9 10 11
and then again:
[1] 11 12 1 2 3 4 5 6 7 8 9 10
...
until the 12th position.
If you need a matrix output
cbind(c(months),embed(c(months, months), 12)[-13,-12])
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
# [1,] 1 12 11 10 9 8 7 6 5 4 3 2
# [2,] 2 1 12 11 10 9 8 7 6 5 4 3
# [3,] 3 2 1 12 11 10 9 8 7 6 5 4
# [4,] 4 3 2 1 12 11 10 9 8 7 6 5
# [5,] 5 4 3 2 1 12 11 10 9 8 7 6
# [6,] 6 5 4 3 2 1 12 11 10 9 8 7
# [7,] 7 6 5 4 3 2 1 12 11 10 9 8
# [8,] 8 7 6 5 4 3 2 1 12 11 10 9
# [9,] 9 8 7 6 5 4 3 2 1 12 11 10
#[10,] 10 9 8 7 6 5 4 3 2 1 12 11
#[11,] 11 10 9 8 7 6 5 4 3 2 1 12
#[12,] 12 11 10 9 8 7 6 5 4 3 2 1
Or another approached suggested by #Marat Talipov
z <- length(months)
i <- rep(seq(z),z) + rep(seq(z),each=z) - 1
matrix(months[ifelse(i>z,i-z,i)],ncol=z)
I'm afraid that you have to come up with a home-made function, something like this one:
rotate <- function(v,i=1) {
i <- i %% length(v)
if (i==0) return(v)
v[c(seq(i+1,length(v)),seq(i))]
}
Couple of examples:
v <- seq(12)
rotate(v,1)
# [1] 2 3 4 5 6 7 8 9 10 11 12 1
rotate(v,-1)
# [1] 12 1 2 3 4 5 6 7 8 9 10 11
You can also use tail and head functions:
x = c(tail(x,n), head(x,-n))
and modify n to rotate n times
The permute package can do this for you:
ap <- allPerms(length(months),
control = how(within = Within(type = "series"),
observed = TRUE))
ap[rev(seq_len(nrow(ap))), ]
(because of the way allPerms() does its work, we need to reverse the order of the rows, which is what the last line does.)
This gives:
> ap[rev(seq_len(nrow(ap))), ]
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,] 1 2 3 4 5 6 7 8 9 10 11 12
[2,] 12 1 2 3 4 5 6 7 8 9 10 11
[3,] 11 12 1 2 3 4 5 6 7 8 9 10
[4,] 10 11 12 1 2 3 4 5 6 7 8 9
[5,] 9 10 11 12 1 2 3 4 5 6 7 8
[6,] 8 9 10 11 12 1 2 3 4 5 6 7
[7,] 7 8 9 10 11 12 1 2 3 4 5 6
[8,] 6 7 8 9 10 11 12 1 2 3 4 5
[9,] 5 6 7 8 9 10 11 12 1 2 3 4
[10,] 4 5 6 7 8 9 10 11 12 1 2 3
[11,] 3 4 5 6 7 8 9 10 11 12 1 2
[12,] 2 3 4 5 6 7 8 9 10 11 12 1
Technically this only works because months is the vector 1:12 and allPerms() returns a permutation matrix of the indices of the thing you want permuted. For different inputs, use ap to index into the thing you want to permute
perms <- ap
perms[] <- months[ap[rev(seq_len(nrow(ap))), ]]
perms

Creating matrix of colnumbers from a vector

Let's say, I have a vector of size 10. How do I create a matrix with position of vector elements arranged like this.
1 2 3 4 5 6 7 8 9 10
2 3 4 5 6 7 8 9 10 1
3 4 5 6 7 8 9 10 1 2
4 5 6 7 8 9 10 1 2 3
5 6 7 8 9 10 1 2 3 4
6 7 8 9 10 1 2 3 4 5
7 8 9 10 1 2 3 4 5 6
8 9 10 1 2 3 4 5 6 7
9 10 1 2 3 4 5 6 7 8
10 1 2 3 4 5 6 7 8 9
You could:
x = 1:10
matrix(x, nrow = length(x), ncol = length(x) + 1, byrow = T)[, -(length(x) + 1)]
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 1 2 3 4 5 6 7 8 9 10
# [2,] 2 3 4 5 6 7 8 9 10 1
# [3,] 3 4 5 6 7 8 9 10 1 2
# [4,] 4 5 6 7 8 9 10 1 2 3
# [5,] 5 6 7 8 9 10 1 2 3 4
# [6,] 6 7 8 9 10 1 2 3 4 5
# [7,] 7 8 9 10 1 2 3 4 5 6
# [8,] 8 9 10 1 2 3 4 5 6 7
# [9,] 9 10 1 2 3 4 5 6 7 8
#[10,] 10 1 2 3 4 5 6 7 8 9
As #flodel noted in the comments, you could, also, build the matrix with an extra row and remove it. And, also, use nicer format: head(matrix(x, nrow = length(x) + 1 , ncol = length(x)), -1).
How about this?
sapply(1:10, function(idx){
vec <- 1:10
if(idx != 1){
vec <- c(vec[idx:10], 1:(idx-1))
}
vec
}
)

Resources