在R中使用字符串引用(部分)数据帧



我有一个大的数据集,我必须根据我想要的搜索特定的代码。例如,化疗由约40个代码编码,这些代码可以出现在称为(diag1, diag2等)的40列中的任何列中。

我正在编写一个函数,该函数根据我想要显示的内容生成绘图。我认为在输入数据帧中指定我想要绘制的内容会很好。因此,例如,如果我只想绘制患者的化疗事件,我将拥有这样的数据框架:

Dataframe name: Style
 Name   SearchIn                                codes         PlotAs  PlotColour
 Chemo  data[substr(names(data),1,4)=="diag"]  1,2,3,4,5,6     |       red

我已经有了一个函数,用于搜索数据帧的特定部分中的代码并标记感兴趣的事件。我不能做的,需要你的帮助,是指一个数据帧(Style$SearchIn[1])使用代码在一个数据帧,如上面

> Style$SearchIn[1]
[1] data[substr(names(data),1,4)=="diag"]
Levels:  data[substr(names(data),1,4)=="diag"] 

我想也许get()会工作,但我不能让它工作:

> get(Style$SearchIn[1])
Error in get(vars$SearchIn[1]) : invalid first argument
enter code here

> get(as.character(Style$SearchIn[1]))
Error in get(as.character(Style$SearchIn[1])) :   
object 'data[substr(names(data),1,5)=="TDIAG"]' not found

, 运行数据(substr(名称(数据),1、5)= = " TDIAG "]

的例子:

  library(survival)
  ex <- data.frame(SearchIn="lung[substr(names(lung),1,2) == 'ph']")
  lung[substr(names(lung),1,2) == 'ph'] #works
  get(ex$SearchIn[1]) # does not work

将R代码存储在字符串中,然后在需要时尝试计算它们并不是一个好主意;对于动态逻辑,几乎总是有更好的解决方案,比如lambdas。

我建议使用列表来存储情节规格,而不是数据框架。这将允许您包含一个函数作为列表的组件之一,该组件可以接受输入数据并返回其子集以进行绘图。

例如:

library(survival);
plotFromSpec <- function(data,spec) {
    filteredData <- spec$filter(data);
    ## ... draw a plot from filteredData and other stuff in spec ...
};
spec <- list(
    Name='Chemo',
    filter=function(data) data[,substr(names(data),1,2)=='ph'],
    Codes=c(1,2,3,4,5,6),
    PlotAs='|',
    PlotColour='red'
);
plotFromSpec(lung,spec);

如果你想存储多个规格,你可以创建一个列表的列表

您是否尝试过使用quote()

我不完全确定你想要什么,但也许你可以存储你想要get()的东西,比如

quote(data[substr(names(data),1,4)=="diag"])
然后使用eval()
eval(quote(data[substr(names(data),1,4)=="diag"]), list(data=data))
例如,

dat <- data.frame("diag1"=1:10, "diag2"=1:10, "other"=1:10)
Style <- list(SearchIn=c(quote(data[substr(names(data),1,4)=="diag"]), quote("Other stuff")))
> head(eval(Style$SearchIn[[1]], list(data=dat)))
  diag1 diag2
1     1     1
2     2     2
3     3     3
4     4     4
5     5     5
6     6     6