2015-01-13 3 views
1

У меня есть функция подмножества, которая принимает объект определенного класса, условие, переданное функции, и добавляет это условие в качестве атрибута объекта.Передача имен переменных для функции в R

subset.survey.data.frame <- function(x, condition, drop=FALSE, inside=FALSE) { 
    if(inside) { 
    condition_call <- deparse(substitute(condition, env=parent.frame(n=1))) 
    } 
    else { 
    condition_call <- substitute(condition) 
    } 

    x[["user_conditions"]] <- unique(c(x[["user_conditions"]],list(condition_call))) 
    cat("Subset Conditions have been added to SDF") 
    x 
} 

Я могу назвать эту функцию, как:

sdf <- subset.survey.data.frame(sdf,dsex =="Male") 

Это добавляет dsex == "Мужчина" в user_conditions атрибута.

Однако, если я хочу называть его из другой функции и цикла, он передавал v1 и v2 вместо фактических имен переменных.

for(i in 1:length(lvls)) { 
    v1 <- rhs_vars[1] 
    v2 <- lvls[i] 
    print(v1) #"dsex" 
    print(v2) #"Male" 
    dsdf <- subset.survey.data.frame(sdf, v1 == v2, inside=T) 

Как я могу изменить функцию подмножества так, что я могу получить имена v1 и v2, а затем добавить условие к объекту?

Вот что SDF, LVLS и rhs_vars выглядит

sdf <- list(user_conditions = list(),default_conditions = list(default_conditions) ,data = data_Laf, weights=weights, pvvars=pvs, fileDescription = f) 

Здесь data_Laf является объектом LaF (http://cran.r-project.org/web/packages/LaF/index.html), вес, ПВС и е все списки.

rhs_vars <- rhs.vars(y ~ dsex + b017451) # from formula.tools package 
> rhs_vars 
[1] "dsex" "b017451" 

LVLS является уровень столбца в dataframe

lvls <- levels(data[,rhs_vars[1]]) 
"Male" "Female" 

Вот рабочий пример:

default_conditions= quote(rptsamp=="Reporting sample") 
sdf <- list(user_conditions = list(),default_conditions = list(default_conditions)) 
class(sdf) <- "Userdefined" 

subset.survey.data.frame <- function(x, condition, drop=FALSE, inside=FALSE) { 
    if(inside) { 
    condition_call <- deparse(substitute(condition, env=parent.frame(n=1))) 
    } 
    else { 
    condition_call <- substitute(condition) 
    } 

    x[["user_conditions"]] <- unique(c(x[["user_conditions"]],list(condition_call))) 
    cat("Subset Conditions have been added to X") 
    x 
} 
sdf <- subset.survey.data.frame(sdf,dsex =="Male") 
print(sdf) 
#This gives the correct answer and adds dsex == "Male" to user conditions 


#Creating some sample data 
dsex =c('1','2','1','1','2','1','1','2','1') 
b017451 <- sample(c(1:100), 9) 
y <- rep(10, 9) 
data <- data.frame(dsex, y, b017451) 
data[,'dsex'] <- factor(data[,'dsex'], levels=c("1", "2"), labels=c('Male','Female')) 
require(formula.tools) 
rhs_vars <- rhs.vars(y ~ dsex + b017451) 
lvls <- levels(data[,rhs_vars[1]]) 

for(i in 1:length(lvls)) { 
    v1 <- rhs_vars[1] 
    v2 <- lvls[i] 
    print(v1) #"dsex" 
    print(v2) #"Male" 
    dsdf <- subset.survey.data.frame(sdf, v1 == v2, inside=F) 
    print(dsdf) 
#this doesnt give the correct answer and adds v1 == v2 to user conditions 

    break 
} 
+1

Если я правильно понял ваш вопрос, 'substitute' должен получить то, что вы ищете. – nrussell

+0

Подставить результаты в v1 == v2 – user1773010

+0

Не могли бы вы добавить другие объекты ('sdf',' lvls', 'rhs_vars')? – nrussell

ответ

1

Как @nrussell намекал, substitute должно помочь вам построить свой выражения. Тогда вам просто нужно их оценить. Вот простой пример,

v1 <- quote(cyl) 
v2 <- 6 
eval(substitute(subset(mtcars, v1==v2), list(v1=v1, v2=v2))) 

Если ваш v1 класс персонажа, вы можете преобразовать его в символ VI as.name(), потому что вам нужен символ, а не символ для выражения для работы.

v1 <- "cyl" 
v2 <- 6 
eval(substitute(subset(mtcars, v1==v2), list(v1=as.name(v1), v2=v2))) 
1

Если вы управляете «внутри» параметра, то это не так просто:

if(inside) condition_call = call(substitute(condition[[1]]), as.name(condition[[2]]), condition[[3]]) 

Это, конечно, предполагает люди только с помощью бинарных условий, но вы можете расширить выше логики.

Смежные вопросы