pmap purrr error: Argument 1 must have names

pmap purrr error: Argument 1 must have names

我打算求和一个data.tablerow-wise,然后加上一个常数。这段代码有什么问题。我特意找pmap_dfr解决方案:

library(data.table)
library(tidyverse)
temp.dt <- data.table(a = 1:3, b = 1:3, c = 1:3)
d <- 10
temp.dt %>% pmap_dfr(., sum, d)   # add columns a b and c and add variable d to it

预期的输出是包含以下行的单列标题:

13 16 19

抛出错误:参数 1 必须有名称。

我已经能够让它与 pmap 和 pmap_dbl 一起工作,但在使用 pmap_dfr 时失败了。此外,我提供的示例是一个玩具示例。我希望 d 变量作为 sum 函数的输入参数,而不是稍后将 d 添加到 row-wise sum.

示例我知道下面会起作用:

temp.dt %>% pmap_dbl(., sum) + d

一个pmap_dfr解决方案是首先t转置数据集。我们稍后可以根据需要重命名列:

temp.dt %>% 
 t() %>% 
   as.data.frame()-> tmp_dt
   pmap_dfr(list(tmp_dt, 10),sum)
# A tibble: 1 x 3
     V1    V2    V3
  <dbl> <dbl> <dbl>
1    13    16    19

一个可能的dplyr-base备选方案:

temp.dt %>% 
   mutate(Sum = rowSums(.) + d) %>% 
  pull(Sum)
[1] 13 16 19

或使用pmap_dbl:

temp.dt %>% 
   pmap_dbl(.,sum) + d
[1] 13 16 19

常规数据帧也会出现问题,因此要将其简化为基本要素,请启动新的 R 会话,去掉 data.table 部分并使用我们有 3x4 [=46= 的地方显示的输入] 这样我们就不会混淆行和列。另请注意 pmap_dfr(sum, d)pmap(sum, d) %>% bind_rows 相同,问题发生在 bind_rows 步骤中。

library(dplyr)
library(purrr)

# test input
temp.df <- data.frame(a = 1:3, b = 1:3, c = 1:3, z = 1:3)
rownames(temp.df) <- LETTERS[1:3]
d <- 10

out <- temp.df %>% pmap(sum, d)     # this works
out %>% bind_rows
## Error: Argument 1 must have names

如错误所述,问题是 out 没有名称,而且它似乎不会为结果提供默认名称。例如,这会起作用——我并不是建议您一定要这样做,而只是试图通过显示使其起作用的最小更改来说明为什么它不起作用:

temp.df %>% pmap(sum, d) %>% set_names(rownames(temp.df)) %>% bind_rows

## # A tibble: 1 x 3
##       A     B     C
##   <dbl> <dbl> <dbl>
## 1    14    18    22

或者可以这样写以避免写两次temp.df

temp.df %>% { set_names(pmap(., sum, d), rownames(.)) } %>% bind_rows

我想我们可以得出结论,pmap_dfr 不是在这里使用的正确函数。

基础 R

当然,这在 base R 中都是微不足道的,因为您可以这样做:

rowSums(temp.df) + d
##  A  B  C 
## 14 18 22 

或更一般地说:

as.data.frame.list(apply(temp.df, 1, sum, d))
##  A  B  C 
## 14 18 22 

as.data.frame.list(Reduce("+", temp.df) + d)
##   X14 X18 X22
##1  14  18  22

data.table

在data.table中我们可以这样写:

library(data.table)

DT <- as.data.table(temp.df)

DT[, as.list(rowSums(.SD) + d)]
##    V1 V2 V3
## 1: 14 18 22

DT[, as.list(apply(.SD, 1, sum, d))]
##    V1 V2 V3
## 1: 14 18 22

另请注意,直接使用 data.table 往往比在其上粘贴另一个级别更快,因此如果您认为通过将 data.table 与 dplyr 一起使用来获得 data.table 的速度优势咕噜咕噜你可能不是。