2017-09-30 4 views
1

Reduceをデータフレームに追加せずに初期値を指定することは可能ですか?機能付き例えばR dplyr:initでReduceで変異させ、group_byの後に

、:データフレームに作用する

f <- function(x, y) if (y<0) -x * y else x + y 

set.seed(0) 
    df <- c(-0.9, sample(c(-0.9, 1:3), 9, replace = TRUE)) %>% tibble() 
    names(df) <- "x" 
    df <- df %>% mutate(id = 'a') 
    df$id[6:10] <- 'b' 
    df <- df %>% group_by(id) %>% mutate(sumprod = Reduce(f, x, acc=TRUE)) %>% ungroup() 
    df$target <- c(0, 3, 4, 5, 7, 3, 2.7, 5.7, 8.7, 10.7) 
    df 

# A tibble: 10 x 4 
     x id sumprod target 
    <dbl> <chr> <dbl> <dbl> 
1 -0.9  a -0.9 0.0 
2 3.0  a  2.1 3.0 
3 1.0  a  3.1 4.0 
4 1.0  a  4.1 5.0 
5 2.0  a  6.1 7.0 
6 3.0  b  3.0 3.0 
7 -0.9  b  2.7 2.7 
8 3.0  b  5.7 5.7 
9 3.0  b  8.7 8.7 
10 2.0  b 10.7 10.7 

目標はカラムtargetあります。私は、Reduceでinitを使ってみましたが、余分な要素が追加されています。 mutate内でこれを使用

Reduce(f, df$x[1:5], acc=TRUE, init=0) 
[1] 0 0 3 4 5 7 

エラー生成:INITが与えられた場合

> df <- df %>% group_by(id) %>% mutate(sumprod = Reduce(f, x, acc=TRUE, init=0)) %>% ungroup() 
Error in mutate_impl(.data, dots) : 
    Column `sumprod` must be length 5 (the group size) or one, not 6 

答えて

2

を、論理的に削減それぞれ、スタート(進行が左から右への場合)またはXの最後に追加します。あなたが要素を必要としない場合は、あなたが最初の要素削除するtail(..., -1)を使用することができます:tidyverse

df %>% 
    group_by(id) %>% 
    mutate(sumprod = tail(Reduce(f, x, acc=TRUE, init=0), -1)) %>% 
    ungroup() 

# A tibble: 10 x 4 
#  x id sumprod target 
# <dbl> <chr> <dbl> <dbl> 
# 1 -0.9  a  0.0 0.0 
# 2 3.0  a  3.0 3.0 
# 3 1.0  a  4.0 4.0 
# 4 1.0  a  5.0 5.0 
# 5 2.0  a  7.0 7.0 
# 6 3.0  b  3.0 3.0 
# 7 -0.9  b  2.7 2.7 
# 8 3.0  b  5.7 5.7 
# 9 3.0  b  8.7 8.7 
#10 2.0  b 10.7 10.7 
2

を、purrr

library(tidyverse) 
df %>% 
    group_by(id) %>% 
    mutate(sumprod = accumulate(.x = x, .f = f, .init = 0)[-1]) %>% 
    ungroup 
# A tibble: 10 x 3 
#  x id sumprod 
# <dbl> <chr> <dbl> 
# 1 -0.9  a  0.0 
# 2 3.0  a  3.0 
# 3 1.0  a  4.0 
# 4 1.0  a  5.0 
# 5 2.0  a  7.0 
# 6 3.0  b  3.0 
# 7 -0.9  b  2.7 
# 8 3.0  b  5.7 
# 9 3.0  b  8.7 
#10 2.0  b 10.7 
から accumulateがあります
関連する問題