我计划逐行对一个data.table求和,并向其添加一个常量。此代码有什么问题。我专门在寻找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添加到行总和中。
我知道以下示例可以工作:
temp.dt %>% pmap_dbl(., sum) + d
答案 0 :(得分:3)
问题也出现在常规数据帧上,因此将其减少到本质上可以开始一个新的R会话,摆脱data.table部分,并在显示3x4 data.frame的地方使用显示的输入,这样我们就不必t混淆行和列。还请注意,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的基础上,这都是不重要的,因为您可以这样做:
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中,我们可以编写:
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往往比在其上附加另一个级别要快,因此,如果您认为通过与dplyr和purrr一起使用来获得data.table的速度优势,则可能不会。
答案 1 :(得分:2)
一种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