Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
126 views
in Technique[技术] by (71.8m points)

r - for-loop or create functions to create matrix (or dataframe) and rename columns

I was trying to generate several new matrix and rename columns and rows with the same actions but different variable values. Follows are the codes I did in a slow way, I tried to use for-loop and functions to do this but could not find a correct approach.

m0 <- 100
N <- 1
CS <- 10.141 
S <- seq (7.72,12.56,0.807)
t <- 15 

per3 <- matrix(nrow = length(S)*N, ncol = t+1)
for (i in 1:dim(per3)[1]) {
  for (j in 1:t+1){
    per3 [,1] <- replicate (n = N, seq (7.72,12.56,0.807))
    per3 [i,j] <- round (abs (rnorm (1, mean = mean(per3[i,1]), sd = 0.2)),digits=3)
  }}
colnames(per3) <- c('physical','t1','t2','t3','t4','t5','t6','t7','t8','t9','t10','t11','t12','t13','t14','t15')
rownames(per3) <- c('S1','S2','S3','CS+','S5','S6')
per3 <- per3 [,-1]

per3_d = matrix(nrow = length(S)*N, ncol = t)
for (i in 1:dim(per3)[1]){
  for (j in 1:t){
    per3_d [i,j] <- abs (per3 [i,j] - 10.141) 
  }
}

g31 <- round (m0 * exp (-0.2 * per3_d),digits = 3)
g32 <- round (m0 * exp (-0.5 * per3_d),digits = 3)
g33 <- round (m0 * exp (-0.9 * per3_d),digits = 3)
g34 <- round (m0 * exp (-1.5 * per3_d),digits = 3)
g35 <- round (m0 * exp (-2 * per3_d),digits = 3)
colnames(g31) <- c('t1','t2','t3','t4','t5','t6','t7','t8','t9','t10','t11','t12','t13','t14','t15')
colnames(g32) <- c('t1','t2','t3','t4','t5','t6','t7','t8','t9','t10','t11','t12','t13','t14','t15')
colnames(g33) <- c('t1','t2','t3','t4','t5','t6','t7','t8','t9','t10','t11','t12','t13','t14','t15')
colnames(g34) <- c('t1','t2','t3','t4','t5','t6','t7','t8','t9','t10','t11','t12','t13','t14','t15')
colnames(g35) <- c('t1','t2','t3','t4','t5','t6','t7','t8','t9','t10','t11','t12','t13','t14','t15')

A same problems as follows, I need to make g31,g32,g33,g34,g35 as dataframes, can I use for loop to do this rather than repeat the actions?

sub1pd<-as.data.frame (per_d)
sub1p<-as.data.frame(per)
sub1g11 <- as.data.frame(g11)
sub1g12 <- as.data.frame(g12)
sub1g13 <- as.data.frame(g13)
sub1g14 <- as.data.frame(g14)
sub1g15 <- as.data.frame(g15)

Thank you very much in advance for your help!


I tried to use the same method you used for per and per_d where I again have same structure but different sd values. However, I am not sure how to do this as I have different steps to generate data for first column and the rest for each per and per_d.

sd <- c(0.2, 0.5, 0.9)
names(sd) <- paste("per", seq_along(sd), sep = "") 
res <- lapply(sd, function(x){ 
  per <- matrix(nrow = length(S)*N, ncol = t+1)
  for (i in 1:dim(per)[1]) {
    for (j in 1:t+1){
      per [,1] <- replicate (n = N, seq (7.72,12.56,0.807))
      per [i,j] <- round (abs (rnorm (1, mean = mean(per[i,1]), sd = x)),digits=3)
      colnames(per) <- paste(t, 1:ncol(per), sep = "")
      per <- as.data.frame (per)
    }
    }
}
)  

enter image description here

question from:https://stackoverflow.com/questions/65834933/for-loop-or-create-functions-to-create-matrix-or-dataframe-and-rename-columns

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In your example you are iterating manually . This is highly inefficient. One way to simplify the code is to iterate using a for loop and there is nothing wrong with that in R (I mention this since many people think otherwise) if you know what and why you are doing. But as an R user you should acquaint yourself with the apply family of functions especially lapply

exps <- c(-0.2, -0.5, -0.9, -1.5, - 2)
names(exps) <- paste("g3", seq_along(exps), sep = "") #name the vactor

res <- lapply(exps, function(x){ #for each x element in the exps vector perform the function
  g <- round(m0 * exp (x * per3_d), digits = 3)
  colnames(g) <- paste("t", 1:ncol(g), sep = "") #avoid typing sequences which can be generated easily
  g <- as.data.frame(g)
  g
}
)  

This way all the data frames will be in a list which will allow much easier further manipulation.

If you really need the list elements in the environment (I highly doubt you really do):

list2env(res, globalenv())

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...