首页 > 解决方案 > 更新重复行中的单个值

问题描述

假设我有一个包含重复记录的数据框:

数据

dt <- data.table(ID=c("A","A","B","B"),Amount1=c(100,200,300,400),
                 Amount2=c(1500,1500,2400,2400),Dupl=c(2,0,1,3))

Dup1 列指示我想要多少重复行。复制后我想更新新行的 amount1 列值。

我开始编写下面的代码,但不知道如何完全实现它

结果

rbind(dt,
      dt %>% 
        filter(Dupl > 0) %>% 
        mutate(Amount1=100))

这是预期的结果,Amount1 中的值已通过将前一行的值除以 2 来更新

#   ID Amount1 Amount2 Dupl
#1:  A     100    1500    2
#2:  A     50     1500    2
#3:  A     200    1500    0
#4:  B     300    2400    1
#5:  B     400    2400    3
#6:  B     200    2400    3
#7:  B     100    2400    3

标签: r

解决方案


我们可以rep通过 'Dupl' 列来查找行序列以扩展数据集,然后用于Reduce更新 'Amount1' 列

library(data.table)
dt[, i1 := seq_len(.N)][rep(seq_len(.N), pmax(Dupl, 1))][, 
  Amount1 := Reduce(function(x, y) x/2, Amount1, accumulate = TRUE), 
     i1][, i1 := NULL][]
#   ID Amount1 Amount2 Dupl
#1:  A     100    1500    2
#2:  A      50    1500    2
#3:  A     200    1500    0
#4:  B     300    2400    1
#5:  B     400    2400    3
#6:  B     200    2400    3
#7:  B     100    2400    3

或者另一种选择是创建一个seq2 的倍数的 uence 并为每个“i1”划分“Amount1”

dt[, i1 := seq_len(.N)][rep(seq_len(.N), pmax(Dupl, 1))][, 
    Amount1 := c(first(Amount1), Amount1[-1]/seq(2, 
           length.out = .N-1, by = 2)), i1][, i1 := NULL][]

或使用tidyverse

library(dplyr)
library(tidyr)
library(purrr)
dt %>%
   mutate(i1 = row_number()) %>%
   uncount(pmax(Dupl, 1)) %>%
   group_by(i1) %>% 
   mutate(Amount1 = accumulate(Amount1, ~ .x/2)) %>%
   ungroup %>%
   select(-i1)
# A tibble: 7 x 4
#  ID    Amount1 Amount2  Dupl
#  <chr>   <dbl>   <dbl> <dbl>
#1 A         100    1500     2
#2 A          50    1500     2
#3 A         200    1500     0
#4 B         300    2400     1
#5 B         400    2400     3
#6 B         200    2400     3
#7 B         100    2400     3

推荐阅读