如果r

时间:2017-06-13 03:52:43

标签: r dplyr conditional-statements cumsum

ve <- c(17, -9, 9, -17, 17, -17, 11, -9, 16, -18, 17, 0, 0, -18, 17, 0, 0, -17, 14, -14, 17, -2, 0, -15, 9, -9, 17, -16, 16, -17, 17, -17, 17, -17, 17, -17, 17, -8, 7, -16, 17, -14, 14, -10, 10, -16, 16, -10, 10, -12, 12, -11, 11, -17, 17, -17, 17, -9, 8, -17, 17, -17, 17, -16, 16, -17, 17, -8, 8, -9, 9, -17, 17, -17, 17, -13, 13, -10, 7, -10, 13, -16, 17, -13, 13, -13, 13, -9, 8, -17, 17, -10, 9, -17, 17, -17, 17, -16, 16, -10, 10, -15, 15, -14, 14, -14, 15, -13, 13, -9, 9, -13, 13, -12, 12, -10, 9, -11, 12, -8, 7, -10, 10, -9, 9, -11, 11, -9, 9, -7, 7, -12, 11, -11, 12, -11, 11, -14, 14, -13, 13, -10, 10, -13, 13, -17, 17, -7, 7, -17, 17, -17, 17, -14, 14, NA)

df <- data.frame(ve = ve, calc = 0)

我需要在列计算中计算cumsum,但它需要重置为零,并在其值变为负值时再次启动。 我已经尝试了几个条件,但它并没有真正起作用......

另外,是否有可能在dplyr中实现这一目标?我是dplyr的新手,并且每当我需要使用依赖值时发现它有点困难。

感谢您的帮助!

它应该是......

     ve calc
1    17    17
2    -9    8
3     9    17
4   -17    0
5    17    17
6   -17    0
7    11    11
8    -9    2
9    16    18
10  -18    0
11   17    17
12    0    17
13    0    17
14  -18    0
15   17    17

如果你看到第14行和第15行,正常的cumsum将是-1和16 但我希望它重置为0而不是-1并继续cumsum,因此下一个将是17

5 个答案:

答案 0 :(得分:1)

我们可以replace NA值为0并使用cumsum

library(dplyr)
df1 <- df %>%
      group_by(grp = cumsum(lag(cumsum(replace(ve, is.na(ve), 0)) < 0, default = TRUE))) %>%
     mutate(calc = cumsum(replace(ve, is.na(ve), 0)), calc = replace(calc, calc < 0, 0)) %>%
      ungroup() %>%
      select(-grp)
head(df1, 15)
# A tibble: 15 x 2
#      ve  calc
#   <dbl> <dbl>
# 1    17    17
# 2    -9     8
# 3     9    17
# 4   -17     0
# 5    17    17
# 6   -17     0
# 7    11    11
# 8    -9     2
# 9    16    18
#10   -18     0
#11    17    17
#12     0    17
#13     0    17
#14   -18     0
#15    17    17

答案 1 :(得分:1)

不使用dplyr,但这应该有效:

ve = as.data.frame(ve)
ve = na.omit(ve)
ve$cumS = 0
ve$cumS[1] = ve$ve[1]

for (i in 2 : length(ve$ve)) {

ve$cumS[i] = ifelse((ve$cumS[i - 1] + ve$ve[i]) < 0,
                     0, (ve$cumS[i - 1] + ve$ve[i]))
}

答案 2 :(得分:1)

这是一个迭代解决方案。我无法想象如何在没有多次传递数据的情况下使用dplyr进行矢量化/使用ve_csum = numeric(length(ve)) current_total = 0 for (i in 1:length(ve)) { if (is.na(ve[i])) { ve_csum[i] = current_total next } current_total = current_total + ve[i] if (current_total < 0) { current_total = 0 } ve_csum[i] = current_total } result = data.frame(ve, ve_csum) ,但我确定其他人会:

<form method="post" action="mailto:example@gmail.com" >
   <div id="accordion" role="tablist" aria-multiselectable="true">
      <div class="card">
         <div class="card-header" role="tab" id="headingOne">
            <h5 class="mb-0">
               <a data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">Collapsible Group Item #1
               </a>
            </h5>
         </div>
         <div id="collapseOne" class="collapse show" role="tabpanel" aria-labelledby="headingOne">
             <div class="card-block">
                <div class = 'container form-group'>
                    <input type = 'text'>
                </div>
             </div>
          </div>
      </div>
      <div class="card">
          <div class="card-header" role="tab" id="headingTwo">
              <h5 class="mb-0">
                  <a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">Collapsible Group Item #2
                  </a>
              </h5>
          </div>
          <div id="collapseTwo" class="collapse" role="tabpanel" aria-labelledby="headingTwo">
              <div class="card-block">
                  <div class = 'container form-group'>
                    <input type = 'text'>
                  </div>
              </div>
          </div>
      </div>
      <div class="card">
           <div class="card-header" role="tab" id="headingThree">
               <h5 class="mb-0">
                    <a class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#collapseThree" aria-expanded="false" aria-controls="collapseThree">Collapsible Group Item #3
                    </a>
               </h5>
           </div>
           <div id="collapseThree" class="collapse" role="tabpanel" aria-labelledby="headingThree">
               <div class="card-block">
                  <div class = 'container form-group'>
                    <input type = 'text'>
                  </div>
               </div>
           </div>
      </div>
      <div class="card row justify-content-center">
           <div class="card-header" role="tab" id="submitForm">
                  <button type="submit" class="btn btn-primary btn-lg btn-block" >Submit for Quote
                  </button>
           </div>    
      </div> 
   </div>
<form>

答案 3 :(得分:0)

> df$calc=ifelse(cumsum(df$ve)<0,0,cumsum(df$ve))

答案 4 :(得分:0)

base R 的 Reducepurrr::accumulate 专为这些场景设计

df$calc <- Reduce(\(.x, .y) ifelse(.x + .y < 0, 0, .x + .y), df$ve, accumulate = TRUE)
df
#>      ve calc
#> 1    17   17
#> 2    -9    8
#> 3     9   17
#> 4   -17    0
#> 5    17   17
#> 6   -17    0
#> 7    11   11
#> 8    -9    2
#> 9    16   18
#> 10  -18    0
#> 11   17   17
#> 12    0   17
#> 13    0   17
#> 14  -18    0
#> 15   17   17
.
.
.

或在purrr

library(purrr)
library(dplyr)

df %>% mutate(calc = accumulate(ve,  ~ ifelse(.x + .y < 0, 0, .x + .y)))