【问题标题】:Sum specified elements of sub-lists对子列表的指定元素求和
【发布时间】:2017-11-06 09:57:59
【问题描述】:

想法:

假设我有一个包含两个向量的列表。然后,我想取第一个向量的第一个元素并将其除以它和列表的第二个向量的第一个元素的总和。然后对第一个列表的所有元素执行此操作。之后,做同样的事情,但使用列表的第二个向量。

列表代码:

tau1 <- list(c(0.43742669 , 0.64024429,  0.39660069,  0.11849773), c(0.5060767, 0.4857891, 0.4553237, 0.5045598))

我的工作代码只有两个向量。

 Tau1 <- vector('list', 2)
for(i in seq_along(tau1)){
  for(j in 1:length(tau1[[1]])){
    Tau1[[i]][[j]] <- tau1[[i]][[j]] / Reduce('+', tau1[[1]][[j]], tau1[[2]][[j]])

  }

}

示例:

列表的第一个元素:

TT1 <- tau1[[1]][[1]]/(tau1[[1]][[1]]+tau1[[2]][[1]])
 [1] 0.4636196

那么对于列表的第二个元素:

 TT2 <- tau1[[2]][[1]]/(tau1[[1]][[1]]+tau1[[2]][[1]])
   [1] 0.5363804

问题:

我想对任意数量的向量执行此操作。例如,

Reduce('+', tau1[[1]][[j]], tau1[[2]][[j]], tau1[[3]][[j]], tau1[[4]][[j]])

我怎样才能自动做到这一点?有什么帮助吗?

【问题讨论】:

  • 使用sum(sapply(tau1, "[[", j)),例如Tau1[[i]][[j]] &lt;- tau1[[i]][[j]] / sum(sapply(tau1, "[[", j))
  • 你能解释一下1在这里是什么意思吗?
  • 编辑了我的评论,检查它是否有效
  • 好的。非常感谢。

标签: r


【解决方案1】:

如果我们使用Reduce,那么我们需要移除[[i]],得到对应的list元素之和,得到vector。然后用第 'j' 个索引子集除以 'tau1[[i]]' 的第 'j' 个元素

Tau1 <- vector('list', 2)
for(i in seq_along(tau1)){
  for(j in seq_along(tau1[[1]])){
    Tau1[[i]][[j]] <- tau1[[i]][[j]] /Reduce(`+`, tau1)[j]
      }

   }

关于 cmets 中提到的错误,如果有非数字元素可能会发生。 OP提到了NULL元素,但NULL作为list中的单个元素出现。所以,有可能是字符"NULL"。例如

tau1 <- list(c(0.43742669 , 0.64024429,  "NULL",  0.11849773), 
        c(0.5060767, 0.4857891, 0.4553237, 0.5045598))

运行上面的代码

f(init, x[[i]]) 中的错误:二元运算符的非数字参数

【讨论】:

  • @Alice 你的原始列表中是否有任何非数字元素,即5 + "10" #Error in 5 + "10" : non-numeric argument to binary operator
  • @Alice 你能举个例子让我看看
  • 我会尽量让它变得如此简单,因为它非常困难。
  • @Alice 另外,如果 length 在 'd' 中相同,那么你也可以这样做 relist(unlist(d)*rep(unlist(y), each = length(d[[1]][[1]])), skeleton = d)
  • 太棒了。谢谢。
【解决方案2】:

要处理任意数量的列表元素,请使用 [[ 的 apply 系列函数。

要在每个子列表中提取j 元素,请使用sapply(tau1, "[[", j)。总结这些元素使用:sum(sapply(tau1, "[[", j))

PS.:您应该使用for(j in 1:length(tau1[[i]]){} 而不是for(j in 1:length(tau1[[1]]){} - 以防万一。

【讨论】:

  • 抱歉,[[ 是否会从列表的两个元素中一一提取所有元素,因为您使用的是 j。对吗?
【解决方案3】:

这是一个基本的 R 单线:

lapply(tau1, "/", do.call(mapply, c(FUN = sum, tau1)))

# [[1]]
# [1] 0.4636196 0.5685838 0.4655351 0.1901875
# 
# [[2]]
# [1] 0.5363804 0.4314162 0.5344649 0.8098125

或者(来自@lmo 的评论):

lapply(tau1, "/", Reduce("+", tau1))

这是一个 purrr 等价物:

library(purrr)

tau1 %>% map(`/`, pmap_dbl(., sum))

# [[1]]
# [1] 0.4636196 0.5685838 0.4655351 0.1901875
# 
# [[2]]
# [1] 0.5363804 0.4314162 0.5344649 0.8098125

【讨论】:

  • 非常感谢您的尝试。我想使用尽可能简单的代码。
  • 一个更简洁的基本 R 实现是lapply(tau1, "/", Reduce("+", tau1))
  • @lmo 是的。我想这取决于实际函数(而不是"+"/sum)是二进制(如"+",强制使用Reduce)还是已经“矢量化”(如sum,允许操作子列表“并行”)。用您的评论编辑了我的答案。谢谢
猜你喜欢
  • 2012-07-05
  • 1970-01-01
  • 2020-06-25
  • 1970-01-01
  • 2019-02-23
  • 2018-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多