R 用户定义函数中的子集,用于将值分配给目标列
我想编写一个函数,根据dataframe中其他三列的值替换目标列的值R 用户定义函数中的子集,用于将值分配给目标列,r,dataframe,subset,variable-assignment,user-defined-functions,R,Dataframe,Subset,Variable Assignment,User Defined Functions,我想编写一个函数,根据dataframe中其他三列的值替换目标列的值 data <-data.frame("exists" = c(1,0,1,0,1,0,0,0,1,1), "specific" = c("yes", NA, "no", NA, NA, NA, NA, NA, NA, "no"), "general" = c(NA, "yes", NA, "yes", "yes", NA, "no", NA, "
data <-data.frame("exists" = c(1,0,1,0,1,0,0,0,1,1),
"specific" = c("yes", NA, "no", NA, NA, NA, NA, NA, NA, "no"),
"general" = c(NA, "yes", NA, "yes", "yes", NA, "no", NA, "no", NA),
"therefore" = 0)
这将提供正确的输出:
> data["therefore"]
therefore
1 1
2 NA
3 0
4 NA
5 1
6 NA
7 NA
8 NA
9 0
10 0
我尝试将代码作为函数编写,以便更容易地将其应用于各种列:
fun <- function (doesitapply, string, speccol, gencol, target) {
data[data[doesitapply] == 0, target] <- NA
data[grepl(string, data[[speccol]], ignore.case=T), target] <- 1
data[data[doesitapply] == 1 & grepl(string, data[[gencol]],
ignore.case=T), target] <- 1
}
这与在用户定义函数中使用列名进行子集设置有关吗?我已经尝试对函数中的所有子集实例使用[[]]
而不是[]
,但是
Error in `[[<-.data.frame`(`*tmp*`, data[[doesitapply]] == 0, target, :
only a single element should be replaced
“[[中的
错误当函数中的代码在函数外部运行时(在设置了所有使用的变量后),它会按预期工作:
doesitapply <- "exists"
string <- "yes"
speccol <- "specific"
gencol <- "general"
target <- "therefore"
data[data[doesitapply] == 0, target] <- NA
data[grepl(string, data[[speccol]], ignore.case=T), target] <- 1
data[data[doesitapply] == 1 & grepl(string, data[[gencol]], ignore.case=T), target] <- 1
doesitapply在R中,用(持久)函数编写函数通常被认为是不好的做法副作用。请尝试重写函数,使其将data
作为参数之一,并使其以所需的状态返回data.frame。这样,您就不必担心环境、作用域等问题。@AkselA感谢您的反馈。今后,我将避免将data
等硬编码参数写入我的函数中注意。
Error in `[[<-.data.frame`(`*tmp*`, data[[doesitapply]] == 0, target, :
only a single element should be replaced
doesitapply <- "exists"
string <- "yes"
speccol <- "specific"
gencol <- "general"
target <- "therefore"
data[data[doesitapply] == 0, target] <- NA
data[grepl(string, data[[speccol]], ignore.case=T), target] <- 1
data[data[doesitapply] == 1 & grepl(string, data[[gencol]], ignore.case=T), target] <- 1