Diberikan:

vars <- c("var1", "var2", "var3", "var4")
mm_exp <- expression(
  f(testm, testmodel = 'test', testgraph = g, truetest1 = TRUE, truetest2 = TRUE), 
  f(testm2, testmodel = 'fg'),
  f(testm3, testmodel = 'fg3')
)

Saya ingin menghasilkan formula menggunakan mm_exp dan semua kombinasi (combn) dari vars untuk dimasukkan ke dalam model:

#y ~ var1 + var2 + var3 + var4 + f(testm, testmodel = "test", testgraph = g, truetest1 = TRUE, 
#  truetest2 = TRUE) + f(testm2, testmodel = "fg") + f(testm3, testmodel = 'fg3')

#y ~ var1 + var2 + var3 + f(testm, testmodel = "test", testgraph = g, truetest1 = TRUE, 
#  truetest2 = TRUE) + f(testm2, testmodel = "fg") + f(testm3, testmodel = 'fg3')

#y ~ var1 + var2 + f(testm, testmodel = "test", testgraph = g, truetest1 = TRUE, 
#  truetest2 = TRUE) + f(testm2, testmodel = "fg") + f(testm3, testmodel = 'fg3')

#y ~ var1 + var4 + f(testm, testmodel = "test", testgraph = g, truetest1 = TRUE, 
#  truetest2 = TRUE) + f(testm2, testmodel = "fg") + f(testm3, testmodel = 'fg3')


#etc.....

Jika saya menyederhanakan mm_exp, saya bisa mendapatkan sesuatu yang mirip dengan apa yang saya inginkan menggunakan reformulate (mengabaikan combn untuk saat ini):

mm_exp_simplify <- expression(
  f(testm, testmodel = 'test', testgraph = g), 
  f(testm2, testmodel = 'fg'),
  f(testm3, testmodel = 'fg3')
)
reformulate(c(vars, sapply(mm_exp_simplify, deparse)), "y")
# y ~ var1 + var2 + var3 + var4 + f(testm, testmodel = "test", 
#     testgraph = g) + f(testm2, testmodel = "fg") + f(testm3, 
#     testmodel = "fg3")

Tetapi jika saya menambahkan kembali truetest1 = TRUE, truetest2 = TRUE itu menyebabkan masalah:

mm_exp <- expression(
  f(testm, testmodel = 'test', testgraph = g, truetest1 = TRUE, truetest2 = TRUE), 
  f(testm2, testmodel = 'fg'),
  f(testm3, testmodel = 'fg3')
)
reformulate(c(vars, sapply(mm_exp, deparse)), "y")
# Error in reformulate(c(vars, sapply(mm_exp, deparse)), "y") : 
#   'termlabels' must be a character vector of length at least one

Saya juga mencoba menggunakan quote tetapi memiliki masalah yang sama:

mm_quote <- quote(
  f(testm, testmodel = 'test', testgraph = g, truetest1 = TRUE, truetest2 = TRUE) + 
    f(testm2, testmodel = 'fg') + f(testm3, testmodel = 'fg3')
)
as.formula(paste0("y ~ ", paste(paste(vars, collapse = "+"), deparse(mm_quote), sep = "+")))
# Error in parse(text = x, keep.source = FALSE) : 
#   <text>:2:39: unexpected '='
# 1: y ~ var1+var2+var3+var4+f(testm, testmodel = "test", testgraph = g, truetest1 = TRUE, 
# 2: y ~ var1+var2+var3+var4+    truetest2 =
#                                          ^

Adakah yang punya saran tentang cara memasukkan truetest1 = TRUE, truetest2 = TRUE dan juga cara mendapatkan versi combn dari rumus?

Terima kasih

0
user63230 20 November 2020, 20:00

1 menjawab

Jawaban Terbaik

Larutan

Untuk menyelesaikan masalah pertama, Anda perlu menggunakan deparse1 alih-alih deparse. Seperti ini:

reformulate(c(vars, sapply(mm_exp, deparse1)), "y")
#> y ~ var1 + var2 + var3 + var4 + f(testm, testmodel = "test", 
#>     testgraph = g, truetest1 = TRUE, truetest2 = TRUE) + f(testm2, 
#>     testmodel = "fg") + f(testm3, testmodel = "fg3")

Tentang masalah kedua Anda, pertama Anda dapat membuat semua kombinasi dengan semua panjang yang mungkin, lalu Anda dapat membuat daftar semua rumus dengan cara ini:

# all vars combinations 
vars_comb <- lapply(seq_along(vars), function(n) combn(vars, n, simplify = FALSE))
vars_comb <- unlist(vars_comb, recursive = FALSE)

# all formulas
lapply(vars_comb, function(v) reformulate(c(v, sapply(mm_exp, deparse1)), "y"))

MENGAPA

Alasan di baliknya terkait dengan nilai default argumen width.cutoff yaitu width.cutoff = 60L di deparse dan width.cutoff = 500L di deparse1.

Lihat saja ini:

# output with deparse
deparse(expression(f(testm, testmodel = 'test', testgraph = g, truetest1 = TRUE, truetest2 = TRUE)))
#> [1] "expression(f(testm, testmodel = \"test\", testgraph = g, truetest1 = TRUE, "
#> [2] "    truetest2 = TRUE))"

# output with deparse and width.cutoff forced to 500
deparse(expression(f(testm, testmodel = 'test', testgraph = g, truetest1 = TRUE, truetest2 = TRUE)), 
        width.cutoff = 500)
#> [1] "expression(f(testm, testmodel = \"test\", testgraph = g, truetest1 = TRUE, truetest2 = TRUE))"

# output with deparse1
deparse1(expression(f(testm, testmodel = 'test', testgraph = g, truetest1 = TRUE, truetest2 = TRUE)))
#> [1] "expression(f(testm, testmodel = \"test\", testgraph = g, truetest1 = TRUE, truetest2 = TRUE))"

deparse pertama membuat vektor dengan panjang 2 yang mengganggu reformulate karena menciptakan komponen rumus yang bukan keluhan.


UNTUK R < 4.0

Jika Anda memiliki R 3.6 seperti yang Anda katakan di komentar, deparse1 tidak tersedia. Oleh karena itu Anda perlu mengatur width.cutoff = 500L di dalam deparse.

Solusinya akan terlihat seperti ini:

# first issue
reformulate(c(vars, sapply(mm_exp, deparse, width.cutoff = 500L)), "y")

# second issue
vars_comb <- lapply(seq_along(vars), function(n) combn(vars, n, simplify = FALSE))
vars_comb <- unlist(vars_comb, recursive = FALSE)
lapply(vars_comb, function(v) reformulate(c(v, sapply(mm_exp, deparse, width.cutoff = 500L)), "y"))
1
Edo 20 November 2020, 17:50