I have an ini-file, read as a list by R (in the example l). Now I want to add further sub-lists along a vector (m) and assign always the same constant to them. My attempt so far:
l <- list("A")
m <- letters[1:5]
n <- 5
for (i in 1:5){
assign(paste0("l$A$",m[i]), n)
}
# which does not work
# example of the desired outcome:
> l$A$e
[1] 5
I don't think that I have fully understood how lists work yet...
Try
L[["A"]][m] <- n
L$A$e
# [1] 5
Data:
L <- list(A = list())
m <- letters[1:5]
n <- 5
Related
I am having problems when saving the results in a for loop.
I am computing a variance (this is not relevant I think) and my code is:
library(dirmult)
n <- 50
p <- 20
size <- 5*p
prob_true <- rep(1/p, p)
multinom <- as.matrix(rmultinom(n, size, prob = prob_true))
zeros <- round(0.5*p*n)
a <- c(as.matrix(multinom))
a[sample(1:(p*n), zeros)] <- 0
data_zeros <- matrix(a, p, n)
dirmult <- dirmult(t(data_zeros))
alpha <- dirmult$gamma
sum_alpha <- (1-dirmult$theta)/dirmult$theta
for (j in ncol(data_zeros)){
A <- alpha/sum_alpha
B <- 1 - A
N <- colSums(data_zeros)
C <- 1 + sum_alpha
var_s_dirm <- list()
var_s_dirm[[j]] <- N[j]*A*B*((N[j]+sum_alpha)/C)
}
In particular I can say that alpha is a vector with 20 values, sum_alpha is a scalar data_zeros is my dataset which has 20 rows and 50 columns and N is the sum of each column of the dataset, so it is a vector with 50 values.
It seems very simple to do what I wanted to do:
I want to get a list with 50 vectors where each one differs form the other by the fact that I multiply for a different value of N.
I really hope that somebody can help me finding the error.
The problem is (probably) you are setting constants in each time j is increased, and in each step you clear the list with the line var_s_dirm <- list()...
See if this works for you
library(dirmult)
n <- 50
p <- 20
size <- 5*p
prob_true <- rep(1/p, p)
multinom <- as.matrix(rmultinom(n, size, prob = prob_true))
zeros <- round(0.5*p*n)
a <- c(as.matrix(multinom))
a[sample(1:(p*n), zeros)] <- 0
data_zeros <- matrix(a, p, n)
dirmult <- dirmult(t(data_zeros))
alpha <- dirmult$gamma
sum_alpha <- (1-dirmult$theta)/dirmult$theta
A <- alpha/sum_alpha
B <- 1 - A
N <- colSums(data_zeros)
C <- 1 + sum_alpha
var_s_dirm <- list()
for (j in 1:ncol(data_zeros)){
var_s_dirm[[j]] <- N[j]*A*B*((N[j]+sum_alpha)/C)
}
output
var_s_dirm
[[1]]
[1] 2.614833 2.327105 2.500483 3.047700 2.233528 2.130223 2.700103 2.869699 2.930213 2.575903 2.198459 2.846096
[13] 2.425448 3.517559 3.136266 2.565345 2.578267 2.763113 2.709707 3.420792
[[2]]
[1] 2.568959 2.286279 2.456615 2.994231 2.194343 2.092850 2.652732 2.819353 2.878806 2.530712 2.159889 2.796165
[13] 2.382897 3.455848 3.081244 2.520339 2.533034 2.714637 2.662168 3.360778
[[3]]
[1] 3.211199 2.857849 3.070769 3.742790 2.742930 2.616064 3.315916 3.524193 3.598509 3.163391 2.699862 3.495207
[13] 2.978622 4.319811 3.851556 3.150424 3.166294 3.393297 3.327711 4.200974
....
I am working in R.
I have n objects all named x followed by a number j = 1,..., n.
eg, for n = 5:
x1, x2, x3, x4, x5
I want to be able to list them all together dynamically depending on the n value:
list(x1,x2,x3,x4,x5)
In other words, I need to write a function that returns a list of those similarly-named objects automatically recognizing at what value of n to stop.
I tried this:
l <- vector()
for (k in (1:n)){
if (k != n){
u <- paste0("x",k, ",")
} else {
u <- paste0("x",k)
}
l <- append(l,u)
}
But obviously returns a list of characters...
Does anyone have an idea of how to do that?
Many thanks for your help.
mget gets a list of objects from their names. Construct the names using paste (vectorized), give it to mget (also vectorized) and you have your list:
l <- mget(paste0("x", 1:n))
I'd suggest trying to use lists from the start, rather than creating a bunch of objects then gathering them into a list. My answer at How to make a list of data frames has examples and discussion about this.
If you want to write a function:
> x1 <- 1:2
> x2 <- 1:3
> x3 <- 2:5
>
> make_list <- function(n){
+ l <- list()
+ for(i in 1:n){
+ l[[i]] <- get(paste0('x',i))
+ }
+ l
+ }
> make_list(3)
[[1]]
[1] 1 2
[[2]]
[1] 1 2 3
[[3]]
[1] 2 3 4 5
> make_list(1)
[[1]]
[1] 1 2
>
Functional way to stack list of 2d matrices into 3d matrix
↑ From this Q I learned I could use simplify2array for this task.
However, it doesn't solve my problem. Unfortunately, I simply don't know how to describe the issue without showing it on an example…
l = list()
l[[1]] = matrix(1:110, nrow=10)
l[[2]] = matrix(110:1, nrow=10)
l = simplify2array(l)
dim(l)
This prints:
10 11 2
Problem is, I would like the dimensions to be set in a different manner. I would like dim(l) to print instead:
2 11 10
How to achieve this?
Use aperm as a generalized transpose (where a is as in the Note at the end).
aa <- aperm(a, 3:1)
dim(aa)
## [1] 2 11 10
Note
We assume that the input a is:
l = list()
l[[1]] = matrix(1:110, nrow=10)
l[[2]] = matrix(110:1, nrow=10)
a <- simplify2array(l)
I am trying to extract all possible square matrices of a matrix,
for example I have this matrix:
S = matrix(1:12, nrow=3)
and I want to extract all possible square matrices from S like the following two (3*3) matrices without modifying the structure of the matrix (keeping the order of rows and columns intact):
I1 = matrix(1:9, nrow=3)
I2 = matrix(4:12, nrow=3)
Thanks
The following should do what you want. First some setup.
# Your data
S <- matrix(1:12, nrow=3)
# Set some helpful variables
n <- nrow(S)
m <- ncol(S)
r <- seq_len(min(n, m)) # Sizes of square submatrices to extract
# Number of sq. submatrices for each r element
r.combs <- structure(choose(n, r)*choose(m, r), names = r)
print(r.combs)
# 1 2 3
#12 18 4
# Total number of square submatrices
sum(r.combs)
#[1] 34
So we expect 34 square submatrices of which 12 are 1x1, 18 are 2x2, and 4 are 3x3.
Next, we loop over all square matrices possible r and all combinations
# Initialize list to hold lists of matrices for each R
res <- structure(vector("list", length(r)), names = paste0("r", r))
for (R in r) {
tmp <- list()
R_n <- combn(n, R, simplify = FALSE) # List all combinations in (n choose R)
R_m <- combn(m, R, simplify = FALSE) # List all combinations in (m choose R)
for(i in seq_along(R_n)) {
for (j in seq_along(R_m)){
tmp <- c(tmp, list(S[R_n[[i]], R_m[[j]], drop = FALSE]))
}
}
res[[R]] <- tmp
}
# See structure
str(res, max.level = 1) # See also str(res)
#List of 3
# $ r1:List of 12
# $ r2:List of 18
# $ r3:List of 4
As seen we have the correct number of submatrices for each size.
Edit:
If you want only submatrices that are "directly" present (rows and columns should be adjacent):
res2 <- structure(vector("list", length(r)), names = paste0("r", r))
for (R in r) {
tmp <- list()
for (i in R:n - R) {
for (j in R:m - R) {
tmp <- c(tmp, list(S[i + 1:R, j + 1:R, drop = FALSE]))
}
}
res2[[R]] <- tmp
}
str(res2, max.level = 1)
#List of 3
# $ r1:List of 12
# $ r2:List of 6
# $ r3:List of 2
With strong inspiration form here.
I would like to calculate name number for a set of given names.
Name number is calculated by summing the value assigned to each alphabet. The values are given below:
a=i=j=q=y=1
b=k=r=2
c=g=l=s=3
d=m=t=4
h=e=n=x=5
u=v=w=6
o=z=7
p=f=8
Example: Name number of David can be calculated as follows:
D+a+v+i+d
4+1+6+1+4
16=1+6=7
Name number of David is 7.
I would like to write a function in R for doing this.
I am thankful for any directions or tips or package suggestions that I should look into.
This code snippet will accomplish what you want:
# Name for which the number should be computed.
name <- "David"
# Prepare letter scores array. In this case, the score for each letter will be the array position of the string it occurs in.
val <- c("aijqy", "bkr", "cgls", "dmt", "henx", "uvw", "oz", "pf")
# Convert name to lowercase.
lName <- tolower(name)
# Compute the sum of letter scores.
s <- sum(sapply(unlist(strsplit(lName,"")), function(x) grep(x, val)))
# Compute the "number" for the sum of letter scores. This is a recursive operation, which can be shortened to taking the mod by 9, with a small correction in case the sum is 9.
n <- (s %% 9)
n <- ifelse(n==0, 9, n)
'n' is the result that you want for any 'name'
You will want to create a vector of values, in alphabetical order, then use match to get their indices. Something like this:
a <- i <- j <- q <- y <- 1
b <- k <- r <- 2
c <- g <- l <- s <- 3
d <- m <- t <- 4
h <- e <- n <- x <- 5
u <- v <- w <- 6
o <- z <- 7
p <- f <- 8
vals <- c(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z)
sum(vals[match(c("d","a","v","i","d"), letters)])
I'm sure there are several ways to do this, but here's an approach using a named vector:
x <- c(
"a"=1,"i"=1,"j"=1,"q"=1,"y"=1,
"b"=2,"k"=2,"r"=2,
"c"=3,"g"=3,"l"=3,"s"=3,
"d"=4,"m"=4,"t"=4,
"h"=5,"e"=5,"n"=5,"x"=5,
"u"=6,"v"=6,"w"=6,
"o"=7,"z"=7,
"p"=8,"f"=8)
##
name_val <- function(Name, mapping=x){
split <- tolower(unlist(strsplit(Name,"")))
total <-sum(mapping[split])
##
sum(as.numeric(unlist(strsplit(as.character(total),split=""))))
}
##
Names <- c("David","Betty","joe")
##
R> name_val("David")
[1] 7
R> sapply(Names,name_val)
David Betty joe
7 7 4