簡體   English   中英

將變量名傳遞給R中的函數

[英]Passing variable names to function in 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")

這會在user_conditions屬性中添加dsex ==“ Male”。

但是,如果我想從另一個函數和循環中調用它,它將傳遞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 ),權重,pv和f都是列表。

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

lvls是數據框中列的級別

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
}

正如@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)))

如果要控制“ inside”參數,那么它不是那么簡單:

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

當然,這假定人們僅使用二進制條件,但是您可以擴展上述邏輯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM