0

我有一个名为“情况”的数据框,其中包含属性列表。

> 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)中的观察结果比我在给定语料库中的子列表多。

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])),])

提前致谢!

4

1 回答 1

0

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

克服此限制的一种方法是使用 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)

我希望这有帮助。

于 2014-03-04T10:20:59.233 回答