I have 10 letters "a b c d e f g h i j" and 200 numbers from 1 to 200 with different number of instances, e.g. five 1s three 2s etc. making up 200 numbers in total.
I would like to assign each number a letter such that each letter has equal frequency.
So in this case I want 20 instances of each letter.
My problem is that I would like to randomly assign letters to numbers.
An example would be:
1 1 1 1 1 2 2 3 3 3 3 3 3 4 5 6 7 7 7 ...until 200
a a a a a e e f f f f f f d i j c c c ...until 200
Start with this-- I'm deliberately not overwriting the existing column in A
Rgames> B<-sample(letters,10)
Rgames> B
[1] "b" "m" "l" "v" "c" "t" "s" "i" "n" "j"
Rgames> A<-sample(1:10,10,replace=TRUE)
Rgames> A
[1] 3 3 2 8 1 5 5 8 2 6
Rgames> A.new<-B[A]
Rgames> A.new
[1] "l" "l" "m" "i" "b" "c" "c" "i" "m" "t"
Then you could cbind if desired to combine A.new and A
Related
I have a below stdin input and I am trying to convert this input to a list.
Input
input <- suppressWarnings(readLines(stdin(), n=31))
8 30
a s 3
b s 5
s a 3
b a 1
c a 10
d a 11
s b 5
a b 3
c b 2
d b 3
a c 10
b c 2
d c 3
e c 7
f c 12
a d 15
b d 7
c d 2
e d 11
f d 2
c e 7
d e 11
f e 3
z e 2
c f 12
d f 2
e f 3
z f 2
e z 2
f z 2
Line 1 first value denotes total number of alphabets , Second value denotes total number of rows.
From Line 2 to Line n. First value denotes starting node , second is ending node and third is cost.
I want to group the alphabets and cost as a list in below manner.
Expected output
> alphabets
$s
[1] "a" "b"
$a
[1] "s" "b" "c" "d"
$b
[1] "s" "a" "c" "d"
$c
[1] "a" "b" "d" "e" "f"
$d
[1] "a" "b" "c" "e" "f"
$e
[1] "c" "d" "f" "z"
$f
[1] "c" "d" "e" "z"
$z
[1] "e" "f"
> cost
$s
[1] 3 5
$a
[1] 3 1 10 11
$b
[1] 5 3 2 3
$c
[1] 10 2 3 7 12
$d
[1] 15 7 2 11 2
$e
[1] 7 11 3 2
$f
[1] 12 2 3 2
$z
[1] 2 2
Any suggestions from where to start.?
Does this give you what you want? I convert your input to a data.frame and the split based on your second column. The output of this differs slightly from yours since split will sort. If you do not want that, you can order the output based on the input.
df <- read.table(textConnection(input[-1]))
alphabets <- split(df$V1, df$V2)
cost <- split(df$V3, df$V2)
# you can do this to reorder how you had it
order <- unique(df$V2)
alphabets[order]
cost[order]
I want to extract the 3rd element of the second vector of the first
sub-list.....
This is the list of vectors
A <- letters[1:4]
B <- letters[5:10]
C <- letters[11:15]
D <- c(1:10)
E <- c(20:5)
Z <- list(x = c(A,B,C), y = c(D, E))
which returns
>Z
$x
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o"
$y
[1] 1 2 3 4 5 6 7 8 9 10 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5
I've tried this
Z[[1]][B[3]]
but it returns
[1] NA
Thank you in advance
There is no way to differentiate between A, B and C when you use them in a vector (c(A, B, C)). I think the elements in x and y should be in a list :
Z <- list(x = list(A,B,C), y = list(D, E))
If you have that we can do :
Z[[1]][[2]][3]
#[1] "g"
This will return 3rd element of the second vector of the first sub-list.
On lists, you have these two options, for example, extract the second value, of the first element of your list. The first system is only valid, when you give names to the elements of your list.
Z$x[2]
Z[[1]][2]
In R-software, suppose you have a vector N1 of length n.
n <- 10
N1 <- letters[rbinom(n, size = 20, prob = 0.5)]
names(N1) <- seq(n)
Suppose you have another vector N2 that is a permutation of the elements of N1
N2 <- sample(N1, size = n, replace = FALSE)
I was wondering if you could help me to find a function in R-software that receives N2 as input and obtains N1 as output, please. Thanks a lot for your help.
Just a guess:
set.seed(2)
n <- 10
N1 <- letters[rbinom(n, size = 20, prob = 0.5)]
names(N1) <- seq(n)
N1
# 1 2 3 4 5 6 7 8 9 10
# "h" "k" "j" "h" "n" "n" "g" "l" "j" "j"
Having repeats makes it difficult to find a return function, since there is not a 1-to-1 mapping. However, if ...
ind <- sample(n)
ind
# [1] 6 3 7 2 9 5 4 1 10 8
N2 <- N1[ind]
N2
# 6 3 7 2 9 5 4 1 10 8
# "n" "j" "g" "k" "j" "n" "h" "h" "j" "l"
We have the same effect that you were doing before, except ...
N2[order(ind)]
# 1 2 3 4 5 6 7 8 9 10
# "h" "k" "j" "h" "n" "n" "g" "l" "j" "j"
all(N1 == N2[order(ind)])
# [1] TRUE
This allows you to get a reverse mapping from some function on N2:
toupper(N2)[order(ind)]
# 1 2 3 4 5 6 7 8 9 10
# "H" "K" "J" "H" "N" "N" "G" "L" "J" "J"
regardless of whether you have an assured 1-to-1 mapping.
Hopefully this is simple, but it seems tricky to explain!
I want to combine two matrices in R, but I'd like to take the first two columns from the first matrix as the first two rows of the combined matrix, then the first column in the second matrix as the third column in the new matrix, then the 4th and 5th columns of the new matrix would be the 3rd and 4th from the first matrix and so and so forth. All matrices have the same row names and same number of rows
Matrix 1:
1 2 1 2 1 2
A a b c d e f
B a b c d e f
C a b c d e f
Matrix 2:
3 3 3
A x x x
B y y y
C z z z
Desired Matrix:
1 2 3 1 2 3 1 2 3
A a b x c d x e f x
B a b y c d y e f y
C a b z c d z e f z
In my example I need this (1,2)(3)(1,2)(3) configuration but as the post title suggests it would be cool to have a generic way of doing this for any configuration of columns from the matrices to be merged.
Make a set of column indexes and then subset a cbind-ed version of the pair of matrices:
grp1 <- 2
grp2 <- 1
sel <- c(rbind(
matrix(1:ncol(mat1),ncol=ncol(mat1)/grp1),
matrix(1:ncol(mat2),ncol=ncol(mat2)/grp2) + ncol(mat1)
))
# 'sel' looks like this before coercion to a vector.
# You can see how the alternating numbers fit together here:
# [,1] [,2] [,3]
#[1,] 1 3 5
#[2,] 2 4 6
#[3,] 7 8 9
cbind(mat1,mat2)[,sel]
1 2 3 1 2 3 1 2 3
A "a" "b" "x" "c" "d" "x" "e" "f" "x"
B "a" "b" "y" "c" "d" "y" "e" "f" "y"
C "a" "b" "z" "c" "d" "z" "e" "f" "z"
Using the following objects as mat1 and mat2:
mat1 <- as.matrix(read.table(text="1 2 1 2 1 2
A a b c d e f
B a b c d e f
C a b c d e f", header=TRUE, check.names=FALSE, stringsAsFactors=FALSE))
mat2 <- as.matrix(read.table(text="3 3 3
A x x x
B y y y
C z z z", header=TRUE, check.names=FALSE, stringsAsFactors=FALSE))
I have an R data frame that looks like this:
z = as.data.frame(list(Col1=c("a","c","e","g"),Col2=c("b","d","f","h"),Col3=c("1,2,5","3,5,7","9,8","1")))
> z
Col1 Col2 Col3
1 a b 1,2,5
2 c d 3,5,7
3 e f 9,8
4 g h 1
(The third column is a text column with comma-separated values.) I would like to convert it to a data frame like this:
a b 1
a b 2
a b 5
c d 3
c d 5
c d 7
e f 9
e f 8
g h 1
Can anyone suggest a way to accomplish this using apply? I'm close using the command below but it's not quite right. Any suggestions on more efficient ways to do this would be appreciated as well...
> apply(z,1,function(a){ids=strsplit(as.character(a[3]),",")[[1]];out<-c();for(id in ids){out<-rbind(out,c(a[1:2],id))};return(out)})
[[1]]
Col1 Col2
[1,] "a" "b" "1"
[2,] "a" "b" "2"
[3,] "a" "b" "5"
[[2]]
Col1 Col2
[1,] "c" "d" "3"
[2,] "c" "d" "5"
[3,] "c" "d" "7"
[[3]]
Col1 Col2
[1,] "e" "f" "9"
[2,] "e" "f" "8"
[[4]]
Col1 Col2
[1,] "g" "h" "1"
You can use ddply.
library(plyr)
ddply(z, c("Col1", "Col2"), summarize,
Col3=strsplit(as.character(Col3),",")[[1]]
)
With reshapeor reshape2
require(reshape2)
merge(cbind(z[,-3], L1=rownames(z)), melt(strsplit(as.character(z$Col3),",")))
gives
L1 Col1 Col2 value
1 1 a b 1
2 1 a b 2
3 1 a b 5
4 2 c d 3
5 2 c d 5
6 2 c d 7
7 3 e f 9
8 3 e f 8
9 4 g h 1