使用R's Reduce为列表中的每个元素求和同名元素

hfsqlsce  于 2022-12-25  发布在  其他
关注(0)|答案(6)|浏览(186)

我在R里有这个名单

> test
[[1]]
[[1]]$right
[1] FALSE

[[1]]$left
[1] FALSE

[[2]]
[[2]]$right
[1] TRUE

[[2]]$left
[1] FALSE

其可以利用该DPUT快速创建

list(list(right = FALSE, left = FALSE), list(right = TRUE, left = FALSE))

现在我想把righttest-list的每个元素中的left元素相加,这样我就得到了一个包含两个元素的列表,如下所示:

> res
$right
[1] 1

$left
[1] 0

我认为R的Reduce是一个很好的选择(尽管我愿意接受任何建议),但我无法弄清楚代码。我尝试了以下代码,但它不起作用...

Reduce(function(x){
     r = sum(x[["right"]]) 
     l = sum(x[["left"]]) 
     v = list(r, v)
 }, test)

我得到这个错误

Error in f(init, x[[i]]) : unused argument (x[[i]])

我想我脑子里有些误解...

tf7tbtn2

tf7tbtn21#

您可以unlist列表并强制rowSumsas.list,这可能更有效。

as.list(rowSums(sapply(test, unlist)))
# $right
# [1] 1
# 
# $left
# [1] 0
  • 数据:*
test <- list(list(right=FALSE, left=FALSE), list(right=TRUE, left=FALSE))
rn0zuynd

rn0zuynd2#

Reduce需要一个接受两个参数的函数,它将得到Reduce的前一个值的结果和传递给Reduce的向量中的一个新元素

Reduce(\(x,y) list(left = x$left + y$left, right = x$right + y$right), test)

就我个人而言,我会使用sapply(或者Map,如果您愿意的话)首先获取left/right元素,然后将它们传递给sum

sapply(test, \(x) x$left) |> sum()

包含MapReduce的版本为:

Map(\(x) x$left, test) |> Reduce(f = \(x, y) x + y)

Map(\(x) x$left, test) |> Reduce(f = `+`)
c0vxltue

c0vxltue3#

使用purrr

library(purrr)
sides <- c("left", "right")

setNames(sides, sides) |>
    map(~(map_int(test, chuck, .x))) |>
    map(reduce, `+`)

##> $left
##> [1] 0
##> 
##> $right
##> [1] 1
ki1q1bka

ki1q1bka4#

由于需要按名称进行聚合,因此可以使用unlisttapply按名称求和:

ll <- list(list(right = FALSE, left = FALSE), list(right = TRUE, left = FALSE))
un <- unlist(ll)
tapply(un, names(un), FUN = sum)
# left right 
#    0     1

您可以先转置:

purrr::transpose(ll) |>
  lapply(Reduce, f = sum)

# $right
# [1] 1
# 
# $left
# [1] 0
o75abkj4

o75abkj45#

除了它们分别生成一个命名向量、一个xtabs/table对象或一个data.frame之外,它们都是相同的。在所有这些方法中,我们都取消列出输入,并将其堆叠到一个两列的 Dataframe 中。然后我们使用xtabs() |> c()xtabs()aggregate

# named vector output
L |>
  unlist() |>
  stack() |>
  xtabs() |>
  c()
## right  left 
##     1     0 

# xtabs/table output
L |>
  unlist() |>
  stack() |>
  xtabs()
## ind
## right  left 
##     1     0 

# data frame output
L |>
  unlist() |>
  stack() |>
  aggregate(values ~ ind, data = _, sum)
##     ind values
## 1 right      1
## 2  left      0

注解

L <- list(list(right = FALSE, left = FALSE), list(right = TRUE, left = FALSE))
rfbsl7qr

rfbsl7qr6#

我将使用这种方法来计算列表的右和左

a_list <- list(list(right = FALSE, left = FALSE),
               list(right = TRUE, left = FALSE))

library(rlist)

(result <- sapply(c(
  "right",
  "left"
), function(x) {
  rlist::list.count(
    a_list,
    eval(parse(text = x))
  )
}))
right  left 
    1     0

相关问题