0

I have a dataframe called 'situations' containing list of attributes.

> 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 ...

I have as many observation in this dataframes (24) than i have sublist in a given corpus.

ID situation names (cnf_01_be) correspond to the name of the sublist (cnf_01_be).

I know how to assign individual attributes :

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

And retrieve them for a specific purpose :

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

But how can I use for example lapply to assign automatically attributes to all the sublist in my corpus ?

I feel like all my trial are going in the wrong direction :

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

...or...

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

Thanks in advance!

Community
  • 1
  • 1
prosodis
  • 55
  • 1
  • 7
  • That's not a list of attributes, it's a dataframe containing a number of variables. Extract them using `[` or `$`. – Thomas Mar 04 '14 at 10:10
  • Do you mean like this : `list1<-as.list(situations[2])` for example ? .... I still don't see how to apply it to multiple sublist right now – prosodis Mar 04 '14 at 10:14

1 Answers1

0

The main problem with using lapply (and similar approaches) is that they cannot normally change the original object of interest, but rather return a new structure. so if you already have a list "corpus" and just want to change its members' attributes you can't usually do that inside a function.

One way to overcome this limitation is to use eval.parent() call instead of the usual assignment. This function evaluates the assignment expression in the parent environment (the environment that called the function), rather than to the local instances (copies) of the objects you assign. if you use this you don't have to return any value.

Another option would be to create a local copy of your corpus list within the function, add to it all the attributes, then return the whole structure from the function and use it to substitute the old list. if your list is big/complex this is probably not a wise choice

Here is a code that does it. note - this is an ugly code. I'm still looking to see if I can make it simpler, but because of the issues above, i'm not sure there is a much simpler option. Anyway, I hope the following will do the trick for you:

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))
       }
   }

}

Note that in order to use it you need to supply your list name (as a character string, and not as a variable), and your data frame. In your case the call would be:

f("corpus",situations)

I hope this helps.

amit
  • 3,332
  • 6
  • 24
  • 32
  • Thanks Amit for your contribution. Unfortunatly, as you can guess My main problem is that I do not know how to compute this function & how to apply it on my sublist. – prosodis Mar 04 '14 at 10:39
  • I edited my comment and added a code that should do the job. I hope that I understood correctly and that this does what you wanted this to do. It is ugly though. sorry – amit Mar 04 '14 at 14:40
  • It seems we are not far from success but remains some problem : I cant seem to access my data this way : `corpus[[cnf_01_be]]` even if names(corpus) answers "cnf_01_be" as first object. I can access it only like this `corpus$cnf_01_be`. Even changing `[[ ]]` by `$` of course didn't do the trick. The functions produces empty string or empty sublist (if i run it with lapply. I tried to `trim` `cmm` and `snames` but it doesn't produce anything either unfortunatly. I almost understand the whole code but I am still missing something. I should access actually the datalike this`corpus$cnf_01_be[[1]]` – prosodis Mar 04 '14 at 18:49
  • do you want to access it? or change its value? and i mean inside the body of my function f, of course. – amit Mar 04 '14 at 19:10