dplyr访问列表中所有元素的子元素

dplyr访问列表中所有元素的子元素,r,dplyr,purrr,glmnet,R,Dplyr,Purrr,Glmnet,我正在尝试将purrr包中的safely()与glmnet包中的lasso回归一起使用。我陷入了交叉验证部分,因为safe()返回一个包含两个元素的列表,$results和$errors。我试图通过使用dplyr只获得$results,但无法让它工作 我可以使用dplyr对单个物种进行交叉验证,但不能对所有物种进行交叉验证 library(dplyr) library(glmnet) library(purrr) data(iris) # Group to perform regression

我正在尝试将purrr包中的safely()与glmnet包中的lasso回归一起使用。我陷入了交叉验证部分,因为safe()返回一个包含两个元素的列表,$results和$errors。我试图通过使用dplyr只获得$results,但无法让它工作

我可以使用dplyr对单个物种进行交叉验证,但不能对所有物种进行交叉验证

library(dplyr)
library(glmnet)
library(purrr)
data(iris)

# Group to perform regressions for every species
grouped <- iris %>% 
  group_by(Species)

# Make model matrices
mm <- grouped %>%
  do(mm = safely(model.matrix)(Sepal.Length ~ Sepal.Width + Petal.Width, data = .)[1])

# Join the dependent values with the model matrices in a tibble
sepallengths <- grouped %>% 
  summarise(Sepal.Length = list(Sepal.Length))
temp <- inner_join(sepallengths, mm, by = "Species")

# Perform cross validation using the tibble above
cv_holder <- temp %>% 
  group_by(Species) %>% 
  # How to get this to work inside dplyr?
  do(cv = safely(cv.glmnet)(.$mm[1]$result, .$Sepal.Length, alpha = 1, nlambda = 100))

# Contains only errors when it should contain the cross validations
cv_holder$cv

# Works for individual lists this way
safely(cv.glmnet)(temp$mm[[1]][1]$result, temp$Sepal.Length[[1]], alpha = 1, nlambda = 100)$result
库(dplyr)
图书馆(glmnet)
图书馆(purrr)
数据(iris)
#分组对每个物种进行回归
分组%
分组(物种)
#制作模型矩阵
毫米%
do(mm=安全(model.matrix)(萼片长度~萼片宽度+花瓣宽度,数据=)[1])
#将依赖值与TIBLE中的模型矩阵连接起来
分离长度%
摘要(萼片长度=列表(萼片长度))
温度%
#如何让它在dplyr内部工作?
do(cv=安全(cv.glmnet)(.$mm[1]$result,.$Sepal.Length,alpha=1,nlambda=100))
#仅在应包含交叉验证时包含错误
cv_持有人$cv
#这种方式适用于单个列表
安全(cv.glmnet)(温度$mm[[1]][1]$result,温度$萼片长度[[1]],alpha=1,nlambda=100)$result
我希望输出是一个tible(cv_holder),带有一列(cv),其中包含每个物种的交叉验证列表。但是,我可以让dplyr只返回错误,例如“rep(1,N)中的simpleError:invalid'times'参数”

这是通过循环实现的方法:

for(i in 1:length(temp$mm)){
    print(safely(cv.glmnet)(temp$mm[[i]][1]$result, temp$Sepal.Length[[i]], alpha = 1, nlambda = 100))
cv_holder$error <- NULL
}
for(i in 1:长度(temp$mm)){
打印(安全(cv.glmnet)(温度$mm[[i]][1]$result,温度$Sepal.Length[[i]],alpha=1,nlambda=100))

cv_holder$error您仍然需要索引到列表中,即使只有1个值

例如:

cv_持有人%
组别(种类)%>%
#如何让它在dplyr内部工作?
do(cv=safe(cv.glmnet)(.$mm[1][[1]]]$result,.$萼片长度[[1]],alpha=1,nlambda=100))

这只是一个观点,但是:在数据整洁时使用tidyverse。在保证的情况下使用for循环。我不认为在显然更加混乱的情况下,尝试将某些内容强制到
dplyr
框架中有什么意义。

我让它与purrr的pull()一起工作,它从每个列表中选择第一项:

cv_holder <- temp %>% 
    group_by(Species) %>% 
    # Using pluck()
    do(cv = safely(cv.glmnet)(pluck(.$mm, 1)$result, pluck(.$Sepal.Length, 1), alpha = 1, nlambda = 100))

# Now works as intended
cv_holder$cv
cv_持有人%
组别(种类)%>%
#使用弹拨()
do(cv=安全(cv.glmnet)(拔出(.$mm,1)$结果,拔出(.$萼片长度,1),α=1,nlambda=100))
#现在一切如愿
cv_持有人$cv
cv_holder <- temp %>% 
    group_by(Species) %>% 
    # Using pluck()
    do(cv = safely(cv.glmnet)(pluck(.$mm, 1)$result, pluck(.$Sepal.Length, 1), alpha = 1, nlambda = 100))

# Now works as intended
cv_holder$cv