将属性列表()分配给R中的子列表

时间:2014-03-04 09:56:08

标签: r attributes lapply levels corpus

我有一个名为'situation'的数据框,其中包含属性列表。

> str(situations)
'data.frame':   24 obs. of  8 variables:
 $ ID.SITUATION          : Factor w/ 24 levels "cnf_01_be","cnf_02_ch",..: 1 2 3 4 5 6 7 8 9 10 ...
 $ ELICITATION.D         : Factor w/ 2 levels "NATUREL","SEMI.DIRIGE": 1 1 1 1 1 1 1 1 2 2 ...
 $ INTERLOCUTEUR.C       : Factor w/ 3 levels "DIALOGUE","MONOLOGUE",..: 2 2 2 2 3 3 3 3 1 1 ...
 $ PREPARATION.D         : Factor w/ 3 levels "PREPARE","SEMI.PREPARE",..: 2 2 2 2 3 3 3 3 3 3 ...
 $ INTERACTIVITE.D       : Factor w/ 3 levels "INTERACTIF","NON. INTERACTIF",..: 2 2 2 2 1 1 1 1 3 3 ...
 $ MEDIATISATION.D       : Factor w/ 3 levels "MEDIATIQUE","NON.MEDIATIQUE",..: 2 2 2 2 2 2 2 2 2 2 ...
 $ PROFESSIONNALISATION.C: Factor w/ 1 level "PRO": 1 1 1 1 1 1 1 1 1 1 ...
 $ ID.TASK               : Factor w/ 5 levels "conference scientifique",..: 1 1 1 1 2 2 2 2 3 3 ...

我在这个数据框(24)中的观察次数与 given corpus中的子列表相同。

ID情况名称(cnf_01_be)对应于子列表的名称(cnf_01_be)。

我知道如何分配个别属性

attributes(corpus$cnf_01_be) = situations[1,]
attributes(corpus$cnf_02_ch) = situations[2,]

检索用于特定目的:

attr(corpus$cnf_01_be, "ELICITATION.D")
attr(corpus$cnf_02_ch, "ELICITATION.D")
attr(corpus$cnf_02_ch, "PREPARATION.D")

但是我如何使用lapply自动将属性分配给我的语料库中的所有子列表?

我觉得我所有的审判都朝着错误的方向发展:

setattr <- function(x,y) {
  attributes(x) <- situations[y,]
  return(attributes)
}

...或...

lapply(corpus,setattr)
lapply(corpus, attributes(corpus) <- situations[c(1:length(situations[,1])),])

提前致谢!

1 个答案:

答案 0 :(得分:0)

使用lapply(和类似方法)的主要问题是它们通常不能更改感兴趣的原始对象,而是返回新结构。因此,如果您已经有一个列表“corpus”并且只想更改其成员的属性,那么通常不能在函数内部执行此操作。

克服此限制的一种方法是使用eval.parent()调用而不是通常的赋值。此函数评估父环境(调用函数的环境)中的赋值表达式,而不是您分配的对象的本地实例(副本)。如果你使用它,你不必返回任何值。

另一种选择是在函数中创建语料库列表的本地副本,将所有属性添加到其中,然后从函数返回整个结构并使用它替换旧列表。如果你的名单很大/很复杂,这可能不是一个明智的选择

这是执行此操作的代码。注意 - 这是一个丑陋的代码。我仍然想看看我是否可以让它变得更简单,但由于上述问题,我不确定是否有更简单的选择。无论如何,我希望以下内容能为您解决问题:

f = function(lname,data) {
   snames = eval.parent(parse(text=paste("names(",lname,")")))
   for (xn in snames) {
       rd = data[match(xn,as.character(data$id)),]
       if (nrow(rd)>0) {
           tmp___ <<-rd[1,]
           cmm = paste("attributes(",lname,"[[",xn,"]]) = tmp___")
           eval.parent(parse(text=cmm))
       }
   }

}

请注意,为了使用它,您需要提供列表名称(作为字符串,而不是变量)和数据框。在您的情况下,呼叫将是:

f("corpus",situations)

我希望这会有所帮助。