วนซ้ำเพื่อสร้างเมทริกซ์หลายตัวใน R (อาจใช้การวาง)

ฉันต้องการสร้างเมทริกซ์ 27 ตัวโดยมี 2 คอลัมน์และจำนวนแถวที่แปรผันได้ ฉันสามารถเขียนโค้ดได้ 27 บรรทัดดังนี้:

 x1 = cbind(rep(1,34), rnorm(34))

 x2 = cbind(rep(1,36), rnorm(36))

....

x27 = cbind(rep(1,k), rnorm(k))

แต่มันต้องมีวิธีที่ดีกว่าในการทำเช่นนั้น ฉันคิดถึงการวนซ้ำบางอย่างเช่นนี้:

aux = c(34, 36, ..., k) # auxiliar variable with number of rows for each matrix

for (i in 1:27) paste("x",i, sep="") =  cbind(rep(1,aux[i]), rnorm(aux[i]))

อย่างไรก็ตาม มันไม่ทำงาน ฉันรู้สึกว่านี่เป็นงานง่ายๆ แต่ฉันไม่มีไอเดียเลย

ความช่วยเหลือใด ๆ ?

ป.ล. : ฉันนึกถึงอาร์เรย์แต่ใช้ไม่ได้ บางทีรายการสามารถทำงานได้ฉันไม่รู้


person Manoel Galdino    schedule 04.02.2011    source แหล่งที่มา
comment
มันดูเหมือนว่าเป็นสิ่งสำคัญสำหรับฉันในการสร้างวัตถุ 27 R (x1, x2, x3,..., x27)   -  person Manoel Galdino    schedule 04.02.2011
comment
มองหาคำตอบของ @Joshua Ulrich เพราะฉันรู้สึกว่าฉันอาจเข้าใจคำถามของคุณผิด หากคุณต้องการเมทริกซ์ที่แตกต่างกันและไม่ได้ต่อเข้ากับรายการ เครื่องหมายถูกสีเขียวควรไปหาเขา   -  person daroczig    schedule 04.02.2011
comment
โซลูชันทั้งสองจะทำงานได้ ขอบคุณทุกคนและฉันทำเครื่องหมายคำตอบของคุณ (@daroczig) เพราะมันได้ผลสำหรับฉัน   -  person Manoel Galdino    schedule 05.02.2011


คำตอบ (4)


คุณต้องการ assign:

for (i in 1:27) {
  assign(paste("x",i,sep=""), cbind(rep(1,aux[i]), rnorm(aux[i])))
}

สิ่งนี้จะสร้างออบเจ็กต์เมทริกซ์ 27 รายการในสภาพแวดล้อมโกลบอลของคุณ

person Joshua Ulrich    schedule 04.02.2011

หากคุณต้องการจำนวนแถวที่แตกต่างกัน คุณจะต้องใช้รายการอย่างแน่นอน ดูตัวอย่างด้านล่าง:

ขั้นแรก ให้ประกาศตัวแปร aux ของคุณซึ่งเก็บจำนวนแถวที่จะสร้าง:

aux <- 50:77

และปล่อยให้วงของคุณหมุน:

x <- vector("list",27) 
for (i in 1:27) {
    x[[i]] <- cbind(rep(1,aux[i]), rnorm(aux[i]))
}

ซึ่งจะคืนรายการเฟรมข้อมูลของคุณ ดูเช่น str(x) สำหรับรายการและ str(x[[1]]) สำหรับโครงสร้างของเมทริกซ์แรก อย่างหลังจะกลับมา:

 num [1:50, 1:2] 1 1 1 1 1 1 1 1 1 1 ...

และคุณพูดถูก: มันสามารถเขียนได้ดีกว่าข้อเสนอนี้มาก ลองมองหา lapply และอื่นๆ แต่คนอื่นๆ จะช่วยคุณในส่วนที่ยุ่งยากนั้น :)


หลังจากแก้ไข: เพิ่ม lapply ตัวอย่าง

ลองใช้โค้ดด้านล่างหากคุณคุ้นเคยกับลูปด้านบน (และแน่นอนว่ามองหา ?lapply):

aux <- 50:77
fun <- function(x) cbind(rep(1,x), rnorm(x))
x <- lapply(aux, fun)
person daroczig    schedule 04.02.2011
comment
แต่คุณไม่ต้องสร้าง x ก่อนเหรอ? บางอย่างเช่น x ‹- list() หรือ x ‹- vector()? ฉันคอมพิวเตอร์ของฉันไม่พบวัตถุ x - person Manoel Galdino; 04.02.2011
comment
ใช่ เราต้องสร้าง x ก่อน ขอบคุณมาก ๆ. ฉันใช้เพียงแค่ x ‹- list() - person Manoel Galdino; 04.02.2011
comment
@Manoel Galdino: ใช่ ขออภัยสำหรับข้อผิดพลาดนี้! ฉันได้แก้ไขคำตอบและเพิ่มบรรทัดพิเศษแล้วยังเพิ่มตัวอย่างด้วย lapply เพื่อให้การแก้ปัญหาเรียบร้อยยิ่งขึ้นในการแลกเปลี่ยน :) - person daroczig; 04.02.2011
comment
จัดสรรล่วงหน้า! กำหนด x <- vector("list",27) ก่อนลูป จากนั้นตั้งค่าแต่ละองค์ประกอบเป็น x ภายในลูป ซึ่งมีประสิทธิภาพมากกว่าการขยายรายการสำหรับการวนซ้ำแต่ละครั้งมาก - person Joshua Ulrich; 04.02.2011
comment
@Joshua Ulrich: จริง ขอบคุณสำหรับการชี้ให้เห็น - นั่นมีประโยชน์จริงๆ ฉันได้แก้ไขคำตอบเพื่อให้ดีขึ้น และฉันเพิ่ง (หลังจากอ่านคำตอบของคุณ) ก็รู้ว่าฉันอาจเข้าใจคำถามผิดเช่นกัน :( - person daroczig; 04.02.2011
comment

ฉันไม่รู้ว่าเซิร์ฟเวอร์ SQL รองรับ GUID เป็นประเภทข้อมูลหรือไม่ ใน MysQL ฉันจะใช้ถ่าน แต่นั่นไม่สำคัญ แค่แสดงความคิดเห็น ส่วนสำคัญคือในวิธีการ:

protected void Button1_Click(object sender, EventArgs e)
{
    con.Open();
    cmd = new SqlCommand("insert into Accom (UserID) values('" + @currentUserID + "')", con);
    cmd.ExecuteNonQuery();

}

คุณไม่ได้ระบุค่าจริงสำหรับ @currentUserID คุณต้องเขียนใหม่เป็นดังนี้:

protected void Button1_Click(object sender, EventArgs e)
{
    SqlParameter param  = new SqlParameter();
    con.Open();
    cmd = new SqlCommand("insert into Accom (UserID) values(@currentUserID)", con);
    //this are the important lines that I'm talking about
    param.ParameterName = "@currentUserID";
    param.Value         = valueOfUserId;
    cmd.Parameters.Add(param);
    cmd.ExecuteNonQuery();    
}

หวังว่าจะช่วยได้

- person Joshua Ulrich; 04.02.2011

หากคุณไม่มีอะไรขัดกับรายการ นี่คือคำถามอื่นของคุณ:

aux <- 30:40
manoel <- sapply(aux, function(x) {
            matrix(NA, ncol = 2, nrow = x)
        }, simplify = FALSE)

> str(manoel)
List of 11
 $ : logi [1:30, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:31, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:32, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:33, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:34, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:35, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:36, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:37, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:38, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:39, 1:2] NA NA NA NA NA NA ...
 $ : logi [1:40, 1:2] NA NA NA NA NA NA ...
person Roman Luštrik    schedule 04.02.2011

โค้ดด้านล่างแสดงวิธีที่ฉันใช้วิธีการของ Joshua Ulrich เพื่อสร้างเมทริกซ์ที่ซับซ้อนขึ้นเล็กน้อย หวังว่าคำตอบนี้จะมีประโยชน์คือการแสดงความยืดหยุ่นที่เป็นไปได้ในการสร้างวัตถุ ถ้าไม่ฉันสามารถลบคำตอบของฉันได้

ฉันสงสัยว่าวิธีการนี้สามารถปรับเปลี่ยนได้อย่างง่ายดายเพื่อสร้างเมทริกซ์ที่มีขนาดแตกต่างกัน เช่น โดยการตั้งค่า nrow หรือ ncol เท่ากับตัวแปร และใช้ rep(q, z) กับตัวแปรบางตัว z เพื่อทำซ้ำองค์ประกอบในเวกเตอร์ภายในคำสั่ง matrix หรือ rbind:

p1.c1 <- 0.10
p2.c1 <- 0.20
p3.c1 <- 0.30
p4.c1 <- 0.40

s1.c1  <- matrix(c(p1.c1, p1.c1, (1 - p1.c1),
                   p1.c1, p1.c1, (1 - p1.c1),
                       0,     0,          1), nrow=3, ncol=3, byrow = TRUE)
s2.c1  <- matrix(c(p2.c1, p2.c1, (1 - p2.c1),
                   p2.c1, p2.c1, (1 - p2.c1),
                       0,     0,          1), nrow=3, ncol=3, byrow = TRUE)
s3.c1  <- matrix(c(p3.c1, p3.c1, (1 - p3.c1),
                   p3.c1, p3.c1, (1 - p3.c1),
                       0,     0,          1), nrow=3, ncol=3, byrow = TRUE)
s4.c1  <- matrix(c(p4.c1, p4.c1, (1 - p4.c1),
                   p4.c1, p4.c1, (1 - p4.c1),
                       0,     0,          1), nrow=3, ncol=3, byrow = TRUE)

n <- 5

p.c1 <- c(p1.c1, p2.c1, p3.c1, p4.c1)

for (i in 1: (n - 1)) {
  assign(paste('xs', i, '.c1', sep=""), matrix(c(p.c1[i], p.c1[i], (1-p.c1[i]),
                                                 p.c1[i], p.c1[i], (1-p.c1[i]),
                                                       0,       0,         1 ), nrow=3, ncol=3, byrow = TRUE))
}
identical(xs1.c1, s1.c1)
identical(xs2.c1, s2.c1)
identical(xs3.c1, s3.c1)
identical(xs4.c1, s4.c1)

for (i in 1: (n - 1)) {
  assign(paste('ys', i, '.c1', sep=""), rbind(c(p.c1[i], p.c1[i], (1-p.c1[i])),
                                              c(p.c1[i], p.c1[i], (1-p.c1[i])),
                                                    c(0,       0,          1)))

}
identical(ys1.c1, s1.c1)
identical(ys2.c1, s2.c1)
identical(ys3.c1, s3.c1)
identical(ys4.c1, s4.c1)
person Mark Miller    schedule 01.03.2018