2010-11-04 16 views
0

J'ai la fonction simple (et fonctionnelle :) suivante qui transforme une information de date qui était auparavant stockée en 2 colonnes (c'est-à-dire Année et Mois) en un certain format de date 'réel'.Existe-t-il un meilleur moyen d'accéder à ces variables qu'attacher?

realDate <- function (table,year,period){ 

    if (is.character(table) == TRUE) 
    { 
    dframe <- get(table) 
    } 

    else{ 
    dframe <- table 
    } 

    attach(dframe) 
    dframe$Date <- as.Date(paste(year,"-",ifelse(period > 9,period,paste("0",period,sep="")),"-01",sep="")) 
    detach(dframe) 
    return(dframe$Date) 

}

Le premier argument est un data.frame (ou le nom de d'une manière) (j'ai besoin d'utiliser lapply avec des vecteurs de caractères contenant plusieurs noms de data.frame). Deuxième argument est la colonne df qui stocke l'année et la période est celle qui stocke le mois. Je suis en train d'apprendre tout ce truc de l'environnement et j'ai le sentiment que cette façon de joindre/détacher n'est pas la bonne façon de le faire (même si cela fonctionne). Existe-t-il un meilleur moyen de faire référence aux arguments donnés "Year" et "Period" dans le cadre de l'instruction paste?

EDIT:

la manière correcte Chose de passer des arguments comme des noms de colonnes? Notez que les colnames de Year et Period peuvent changer de data.frame à data.frame. Si j'utilise la fonction que vous avez suggérée, je reçois soit:

head(realDate(mydf,"Jahr","Periode")) # German for year and period 
Error in charToDate(x) : 
character string is not in a standard unambiguous format 

or 

Error in paste(year, "-", ifelse(period > 9, period, paste("0", period, : 
object 'Jahr' not found 

HTH aide.

+0

Certains exemples de données seraient utiles. Ce que je ne comprends pas, c'est que vous passez en 'year' et' period' comme arguments. Comment cela se rapporte-t-il à 'dframe' - c'est-à-dire pourquoi attacher? Y at-il une colonne dans 'dframe' /' table' nommée "year2 et" period ", auquel cas vous n'avez pas besoin de les passer en arguments, utilisez simplement' with() 'ou' within() '. –

+0

La raison pour laquelle je passe l'année et la période en argument est que les étiquettes changent dans mon cas.La base de données que je dois utiliser, utilise différentes étiquettes pour l'année.C'est parfois un label anglais, parfois suisse/allemand. –

Répondre

7

Utilisation with() ou within() --- tous deux évaluer une expression de R dans un environnement particulier si with(f00, EXPR) évaluera l'expression EXPR au sein d'un environnement spécial qui « contient » les éléments/composants de foo. within() vous permet de modifier/remplacer dans cet environnement spécial.

La version traduite directement de votre fonction (principale bit) serait:

dframe <- within(dframe, 
       Date <- as.Date(paste(year,"-", 
             ifelse(period > 9, period, 
               paste("0", period, sep = "")), 
             "-01", sep = ""))) 

, mais il n'y a pas besoin de forcer la copie la trame de données juste pour ajouter une colonne à retourner avant de jeter ce cadre de données (vous ne renvoyez pas le bloc de données modifié, seulement la date).

Au lieu de cela, il suffit d'utiliser with(), et laisse supposer que vous vouliez dire dframe/table comprennent une year et une colonne period, auquel cas vous ne, pas besoin de passer en année/période (sinon je ne vois pas pourquoi vous besoin de attach):

realDate <- function (table) { 
    if (is.character(table) == TRUE) { 
     dframe <- get(table) 
    } else { 
     dframe <- table 
    } 
    resDate <- with(dframe, 
        as.Date(paste(year,"-", 
            ifelse(period > 9, period, 
             paste("0", period, sep = "")), 
            "-01", sep = "")) 
    return(resDate) 
} 
+0

Désolé, désolé, désolé Oui, votre hypothèse est parfaitement juste, je voulais dire que dframe/table contient ces Je le passe parce que je ne veux pas coder en dur ces noms de colonnes –

+0

Si vous ne voulez pas coder en dur, alors vous êtes dans la position de devoir 'get (year)' et 'get (period)' Dans votre appel 'as.Date()', alors IIRC, à cause du 'with', le' get() 'devrait être évalué dans l'objet et devrait être und, sans attacher.Vous pouvez donc utiliser le code dans la réponse que j'ai fournie, il suffit d'utiliser 'get (period)' et 'get (year)' au lieu de 'period' &' year'. C'était en partie ma confusion parce que vous avez réalisé que vous pourriez avoir besoin d'utiliser 'get()' sur l'argument 'table' mais que vous utilisiez' period' et 'year' tel quel. –