R语言中用管道符调用which()函数处理glmnet结果报错的解决方法
glmnet输出用管道调用which()报错的解决办法
分步代码运行正常:
k <- coef.glmnet(glmnet(df[, !(names(df) == "errs")], df[, "errs"], alpha = 1, lambda = lambdas, intercept = FALSE)) z <- which(k != 0, arr.ind = TRUE, useNames = TRUE)
但用管道改写后报错:
k <- coef.glmnet(glmnet(df[, !(names(df) == "errs")], df[, "errs"], alpha = 1, lambda = lambdas, intercept = FALSE)) %>% which(. != 0, arr.ind = TRUE, useNames = TRUE)
报错信息:
Error in which(., . != 0, arr.ind = TRUE, useNames = TRUE) :
unused argument (. != 0)
错误原因
%>%会把左侧的结果作为右侧函数的第一个参数传递。原分步代码里,which(k !=0, ...)的第一个参数是k !=0生成的逻辑矩阵;但管道改写时,你把coef的结果直接传给了which的第一个参数,又额外传入. !=0作为第二个参数,而which的第二个参数是arr.ind,所以就会提示“未使用的参数”。
可行解决办法
方法1:用大括号包裹表达式,指定逻辑条件为which的第一个参数
k <- coef.glmnet(glmnet(df[, !(names(df) == "errs")], df[, "errs"], alpha = 1, lambda = lambdas, intercept = FALSE)) %>% { which(. != 0, arr.ind = TRUE, useNames = TRUE) }
大括号会改变管道的默认参数传递规则,此时.代表左侧传入的coef结果,which(. !=0, ...)就和原分步代码的逻辑一致了。
方法2:拆分逻辑判断与which调用
先通过管道完成!=0的逻辑比较,再把结果传给which:
k <- coef.glmnet(glmnet(df[, !(names(df) == "errs")], df[, "errs"], alpha = 1, lambda = lambdas, intercept = FALSE)) %>% `!=`(0) %>% which(arr.ind = TRUE, useNames = TRUE)
这里!=作为函数调用,左侧结果是第一个参数,0是第二个参数,生成逻辑矩阵后再传给which,完全匹配原分步代码的执行流程。
方法3:用匿名函数显式处理
k <- coef.glmnet(glmnet(df[, !(names(df) == "errs")], df[, "errs"], alpha = 1, lambda = lambdas, intercept = FALSE)) %>% (function(x) which(x != 0, arr.ind = TRUE, useNames = TRUE))
匿名函数接收左侧传入的coef结果作为x,然后执行和原分步代码一样的which调用。
内容的提问来源于stack exchange,提问作者entropy
相关产品推荐
相关产品推荐

