R - 循环从一系列中的第一个中减去每个连续值

时间:2017-08-23 01:20:14

标签: r

我正在修补这个循环(我是新写的循环,但试图学习)。

我的目标是x == 1在第一个匹配时存储z的值,然后在每个连续的z值上从第一个值中减去该z值。如果x == 0那么它什么都不做(不确定我是否必须告诉代码在x ==0时什么都不做?)

This is my dummy data: 

x <- c(0,0,1,1,1,0,1,1,1,1,0,0,0)
z <- c(10,34,56,43,56,98,78,98,23,21,45,65,78)
df <- data.frame(x,z)

for (i in 1:nrow(df)) {
  if (df$x[i] == 1)
  first_price <- df$z[i]
  df$output <- first_price - df$z
  }
}

我有if (df$x == 1) 然后我想保存第一个价格......所以first_price <- df$z[i] i在这里,这意味着系列中的第一个对吗?

然后我的输出......我想从每个连续的价格中减去第一个价格。如果我用[i]确定第一个价格,这是正确的方法吗?如果我离开df $ z那么那么每次在循环中取下一个价格并减去 first_price <- df$z[i]

看见视觉: enter image description here

****** ****进展

> for (i in 1:nrow(df)) {
+   if (df$x[i] == 1) {
+   first_price <- df$z[1]
+     df$output <- first_price - df$z
+     }
+ }
> df$output
 [1]   0 -24 -46 -33 -46 -88 -68 -88 -13 -17 -35 -55 -68

如果我添加[1]分配df $ z中的第一个元素,这实际上修复了第一个元素然后减去每个连续,现在它需要基于规则并且理解这只是情况何时df$x == 1

1 个答案:

答案 0 :(得分:2)

这应该对你有用

library(dplyr)
library(data.table)
ans <- df %>%
         mutate(originalrow = row_number()) %>%    # original row position
         group_by(rleid(x)) %>%
         mutate(ans = first(z) - z) %>%
         filter(x==1)

# # A tibble: 7 x 5
# # Groups:   rleid(x) [2]
      # x     z originalrow `rleid(x)`   ans
  # <dbl> <dbl>       <int>      <int> <dbl>
# 1     1    56           3          2     0
# 2     1    43           4          2    13
# 3     1    56           5          2     0
# 4     1    78           7          4     0
# 5     1    98           8          4   -20
# 6     1    23           9          4    55
# 7     1    21          10          4    57

vans <- ans$ans
# [1]   0  13   0   0 -20  55  57  

修改

保留所有行,并输出0,其中x == 0

ans <- df %>%
         mutate(originalrow = row_number()) %>%
         group_by(rleid(x)) %>%
         mutate(ans = ifelse(x==0, 0, first(z) - z))

# # A tibble: 13 x 5
# # Groups:   rleid(x) [5]
       # x     z originalrow `rleid(x)`   ans
   # <dbl> <dbl>       <int>      <int> <dbl>
 # 1     0    10           1          1     0
 # 2     0    34           2          1     0
 # 3     1    56           3          2     0
 # 4     1    43           4          2    13
 # 5     1    56           5          2     0
 # 6     0    98           6          3     0
 # 7     1    78           7          4     0
 # 8     1    98           8          4   -20
 # 9     1    23           9          4    55
# 10     1    21          10          4    57
# 11     0    45          11          5     0
# 12     0    65          12          5     0
# 13     0    78          13          5     0