【问题标题】:Convert loop to apply while building list在构建列表时将循环转换为应用
【发布时间】:2019-06-09 20:38:12
【问题描述】:

我正在尝试使用应用函数而不是循环在 R 中构建列表列表,但我无法将工作循环转换为 lapply 格式。请允许我再解释一下情况:

我在 R (getDetails) 中有一个函数,它检索与我传递给函数的参数相关的详细信息,并在列表中返回结果。如果我将单个记录传递给该函数,该函数运行良好,并且我还构建了一个循环,允许我一次循环遍历数据帧,并将数据帧的元素逐行传递给我的该函数又将一个列表返回到我的列表列表的第 i 个元素 (detailsList[[i]])。我试图弄清楚如何将我的 for 循环转换为应用函数。你能帮我解决这个问题吗?我创建了一个玩具示例,如果我可以开始工作,我可以将其推广到我的实际 getDetails 函数。

#use cars dataset for an example
data(cars)
#get number of rows
numrows<-dim(cars)[1]
#initialize empty list
detailsList<-vector("list", numrows)

#This is a toy example of the loop I want to convert to an apply
#I'm having trouble because this builds up a list and returns the results
#to my detailsList one element at a time and I'm not sure how to do this 
#in an apply.
for (i in 1:numrows){
  detailsList[[i]]<-getDetails(cars[i,])
}

detailsList

getDetails<-function(parameters){
   valueA<-parameters[1]+45
   valueB<-parameters[1]+10
   list(valueA, valueB)
}

更新:

我以为我只是想通了,但似乎当我这样做时,我的列表中出现了第三个维度,所以当我使用它时:

allDetails <- lapply(1:numrows, function(i)  getDetails(cars[i,]))

第一个列表的第二个元素只能使用allDetails[[1]][[1]][2] 访问,而不是像我希望的那样使用allDetails[[1]][2]。有谁知道我在这里做错了什么?

【问题讨论】:

  • 注意:apply functions are loops(只是隐藏的)。
  • 谢谢,@parfait。我知道应用函数与循环相同,但这正是我试图将循环转换为应用的原因——问题是,我不确定在这个示例中如何处理它,因为我'正在我的循环中构建一个列表,尽管我过去使用过 apply 函数没有任何困难(因为我没有在循环内构建列表列表),但我之前从未真正使用 apply 函数完成此操作。我用我最初认为正确的内容更新了我的回复,但似乎它在列表列表中添加了第三个维度。
  • 第三个元素?您的函数返回列表中的两个元素。假设值对象是单项向量,请尝试将 list() 替换为 c()
  • 啊,是的。对不起。我的意思是第二个。这就是我使用玩具示例并将其应用于我的实际工作(确实有第三个元素)所得到的。我已经更新了更新。我将尝试使用 c() 而不是 list。感谢您的建议!
  • @Parfait,你是男人(或女人)!非常感谢您的帮助。在我的函数末尾只使用 c() 而不是 list() 就可以了。非常感谢!

标签: r list loops lapply sapply


【解决方案1】:

我想我是在@Parfait 的一点帮助下才弄明白的(谢谢@Parfait!)。如果其他人正在寻找答案,这对我有用,但我欢迎任何其他答案:

lapply(1:numrows, function(i)  getDetails(cars[i,]))

我不得不修改我的函数以返回一个向量而不是一个列表:

getDetails<-function(parameters){
   valueA<-parameters[1]+45
   valueB<-parameters[1]+10
   c(valueA, valueB)
}

【讨论】:

    【解决方案2】:

    这是你用vapply编写的循环

    out <- vapply(1:nrow(cars), 
                  function (i) {
                    valA <- .subset2(cars, 1)[i] + 45L
                    valB <- .subset2(cars, 1)[i] + 10L
                    c(valA, valB)
                  }, numeric(2))
    t(out) 
    #       [,1] [,2]
    # [1,]   49   14
    # [2,]   49   14
    # [3,]   52   17
    # [4,]   52   17
    # [5,]   53   18
    # [6,]   54   19
    # [7,]   55   20
    # ...
    # (returns an array instead of a list, but that can be changed easily).
    

    顺便说一句,我不知道你的最终目标是什么,但就这个例子而言,为什么 any 循环呢?

    # vectorized
    cbind(.subset2(cars, 1) + 45L, .subset2(cars, 1) + 10L)
    #      [,1] [,2]
    # [1,]   49   14
    # [2,]   49   14
    # [3,]   52   17
    # [4,]   52   17
    # [5,]   53   18
    # [6,]   54   19
    # [7,]   55   20
    # ...
    # or similar result with
    # getDetails(cars) (version with c())
    

    【讨论】:

    • 谢谢@nate。 “循环”必须发生,因为我必须一次在外部 3d 方应用程序中查找详细信息。这只是一个玩具示例,可以帮助我弄清楚如何在我更复杂的程序中实现。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-30
    • 1970-01-01
    • 1970-01-01
    • 2020-03-29
    • 1970-01-01
    相关资源
    最近更新 更多