首页 > 解决方案 > 如何评估嵌套列表中的表达式

问题描述

我想在数据框中的所有列上迭代一个函数,每列的函数具有不同的参数。我正在尝试通过嵌套的 lapply 来做到这一点。

然而结果不是我所期望的,我希望将值从第一个 lapply 传递到第二个,但如下面的结果所示,第二个 lapply 打印“var”而不用“var1”等替换它。

我应该如何解决它?


# sample data frame
 df <- data.frame(date = seq.Date(from = as.Date("2021-01-01"), by = "day", length.out = 100),
                 var1 = rnorm(100),
                 var2 = rnorm(100),
                 var3 = rnorm(100))

# list 1
var.list <- setdiff(names(df),"date")

# list 2
pen.list <-  c("mean(df[[var]])", "log(mean(df[[var]]))", "log(mean(df[[var]]))^2", "mean(df[[var]])^2/2")


lapply(var.list, function(var){
  lapply(pen.list, function(pen){
    print(var)
    print(pen)
    plot(cpt.mean(df[[var]],penalty = "Manual", method = "PELT", pen.value = noquote(pen)))
  })
  })

#Result
[1] "var1"
[1] "mean(df[[var]])"
[1] "var1"
[1] "log(mean(df[[var]]))"
[1] "var1"
[1] "log(mean(df[[var]]))^2"
[1] "var1"
[1] "mean(df[[var]])^2/2"
[1] "var2"
[1] "mean(df[[var]])"
[1] "var2"
[1] "log(mean(df[[var]]))"
[1] "var2"
[1] "log(mean(df[[var]]))^2"
[1] "var2"
[1] "mean(df[[var]])^2/2"
[1] "var3"
[1] "mean(df[[var]])"
[1] "var3"
[1] "log(mean(df[[var]]))"
[1] "var3"
[1] "log(mean(df[[var]]))^2"
[1] "var3"
[1] "mean(df[[var]])^2/2"

标签: rlapply

解决方案


可能我们需要使用字符串插值

library(stringr)
lapply(var.list, function(var){
  lapply(pen.list, function(pen){
    print(var)
    print(str_replace(pen, 'var', sprintf('"%s"', var) ))
    #plot(cpt.mean(df_today[[var]],penalty = "Manual", method = "PELT", pen.value = noquote(pen)))
  })
  })

-输出

[1] "var1"
[1] "mean(df_today[[\"var1\"]])"
[1] "var1"
[1] "log(mean(df_today[[\"var1\"]]))"
[1] "var1"
[1] "log(mean(df_today[[\"var1\"]]))^2"
[1] "var1"
[1] "mean(df_today[[\"var1\"]])^2/2"
[1] "var2"
[1] "mean(df_today[[\"var2\"]])"
[1] "var2"
[1] "log(mean(df_today[[\"var2\"]]))"
[1] "var2"
[1] "log(mean(df_today[[\"var2\"]]))^2"
[1] "var2"
[1] "mean(df_today[[\"var2\"]])^2/2"
[1] "var3"
[1] "mean(df_today[[\"var3\"]])"
[1] "var3"
[1] "log(mean(df_today[[\"var3\"]]))"
[1] "var3"
[1] "log(mean(df_today[[\"var3\"]]))^2"
[1] "var3"
[1] "mean(df_today[[\"var3\"]])^2/2"
...

只是为了确认它通过evaluation起作用

df_today <- df
lapply(var.list, function(var){
  lapply(pen.list, function(pen){
    print(var)
    eval(parse(text = str_replace(pen, 'var', sprintf('"%s"', var) )))
  })
  })

-输出

[1] "var1"
[1] "var1"
[1] "var1"
[1] "var1"
[1] "var2"
[1] "var2"
[1] "var2"
[1] "var2"
[1] "var3"
[1] "var3"
[1] "var3"
[1] "var3"
[[1]]
[[1]][[1]]
[1] -0.02421389

[[1]][[2]]
[1] NaN

[[1]][[3]]
[1] NaN

[[1]][[4]]
[1] 0.0002931563


[[2]]
[[2]][[1]]
[1] 0.0746259

[[2]][[2]]
[1] -2.595268

[[2]][[3]]
[1] 6.735414

[[2]][[4]]
[1] 0.002784513


[[3]]
[[3]][[1]]
[1] 0.01060897

[[3]][[2]]
[1] -4.546055

[[3]][[3]]
[1] 20.66662

[[3]][[4]]
[1] 5.627514e-05

推荐阅读