R中有一种方法,如果满足另一列中的特定条件,则该列的值应为上面的值

问题描述 投票:-1回答:1

我希望myrate列中的值为

  1. [myrate的第一个值应为rupee(负)amt
  2. 对于myrate列的第二行,应为myrate的第一个值(在点1生成的值)减去Rupee列的第二个值,如果第一行和第二行中的“名称”相同
  3. 步骤2的逻辑应继续进行,直到达到Name列中的新值为止(在这种情况下为“ sss”)4.再次在“ sss”名称的第二行中,继续执行步骤2的逻辑

我尝试使用dplyr给出了某些迭代的正确答案,但对于其他迭代却失败了。

table example

r loops dplyr row bigtable
1个回答
0
投票

尝试一下。我添加了一个辅助函数来计算myrate。不用检查名称,我只是将df除以Name,而是对每个Name进行计算,最后将它们绑定在一起。

# Example data

df <- data.frame(
  Name = c(rep("kkk", 3), rep("sss", 3), rep("ttt", 2)),
  Amt = c(20:27),
  Rupee = c(11, 333, 65, 90, 36, 71, 69, 32)
)
df
#>   Name Amt Rupee
#> 1  kkk  20    11
#> 2  kkk  21   333
#> 3  kkk  22    65
#> 4  sss  23    90
#> 5  sss  24    36
#> 6  sss  25    71
#> 7  ttt  26    69
#> 8  ttt  27    32

# Helper function
myrate <- function(df) {
  # Init myrate = 0
  df$myrate <- 0
  # Add id = row number
  df$id <- 1
  df$id <- cumsum(df$id)
  # Loop over id or rows
  for (i in df$id) {
    df$myrate[i] <- 
      if (i == 1) {
        df$Rupee[i] - df$Amt[i]
      } else {
        df$myrate[i] <- df$myrate[i - 1] - df$Rupee[i]
      }
  }
  df["id"] <- NULL
  df
}

# Computation
library(dplyr)

df %>% 
  # Split by Name
  split(.$Name) %>%
  # Compute myrate for each Name
  lapply(myrate) %>%
  # Bind back in one df
  bind_rows()
#>   Name Amt Rupee myrate
#> 1  kkk  20    11     -9
#> 2  kkk  21   333   -342
#> 3  kkk  22    65   -407
#> 4  sss  23    90     67
#> 5  sss  24    36     31
#> 6  sss  25    71    -40
#> 7  ttt  26    69     43
#> 8  ttt  27    32     11

reprex package(v0.3.0)在2020-04-05创建

© www.soinside.com 2019 - 2024. All rights reserved.