首页 > 解决方案 > 为在 R 中存储为字符串的嵌套列表的索引赋值

问题描述

我有一个嵌套列表索引的数据框,它已存储为字符串。举一个简化的例子:

df1 <- data.frame(x = c("lst$x$y$a", "lst$x$y$b"), stringsAsFactors = F)

这些是以下列表的坐标:

lst <- list(x=list(y=list(a="foo",b="bar",c="")))

我想使用df1.

一种尝试是

do.call(`<-`, list(eval(parse(text = df1[1,1])), "somethingelse"))

但这似乎不起作用。相反,它分配"something"foo.

我对使用不太满意eval(parse(text=))(维护代码将成为一场噩梦),但我知道我可能别无选择。

欢迎任何提示。

标签: reval

解决方案


让我们考虑3种情况:

情况1

do.call(`<-`, list("lst$x$y$a", "somethingelse"))

这将在您的工作区中创建一个名为的新变量lst$x$y$a,因此以下两个命令将调用不同的对象。(前者是你存储的对象lst,后者是新变量。你需要用反引号调用它,因为它的名字会混淆 R。)

> lst$x$y$a   # [1] "foo"
> `lst$x$y$a` # [1] "somethingelse"

案例2

do.call(`<-`, list(parse(text = "lst$x$y$a"), "somethingelse"))

你大部分都能得到你所期望的,但仍然会出现错误:

分配的左侧无效(do_set)

让我们检查:

> parse(text = "lst$x$y$a")  # expression(lst$x$y$a)

它属于 class expression,并且操作员<-似乎不接受这个 class 到左侧。


案例3

这将实现您想要的:

do.call(`<-`, list(parse(text = "lst$x$y$a")[[1]], "somethingelse"))

如果放在[[1]]一个对象后面expression,一个call对象将被提取并在操作符中生效<-

> lst

# $x
# $x$y
# $x$y$a
# [1] "somethingelse"
# 
# $x$y$b
# [1] "bar"
# 
# $x$y$c
# [1] ""

推荐阅读