【问题标题】:Update individual values in duplicate rows更新重复行中的单个值
【发布时间】:2019-12-26 02:28:42
【问题描述】:

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

数据

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


    【解决方案1】:

    我们可以replicate '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
    

    或者另一种选择是创建一个 2 的倍数的 sequence 并为每个 '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
    

    【讨论】:

    • 是否可以在创建副本的同时更改 Amount1 列中的值?
    • @capiono 你能检查我的更新吗?这是您的预期输出吗
    • @capiono 如果您检查我的前两个解决方案,它会通过复制相同的行值来进行更新
    • 感谢@arun 帮助我解决这个问题。我已经更新了我的问题。我对所有列都感兴趣,但是 Amount1 列中的值需要通过将前一行的值除以 2 来更新新行中的值
    猜你喜欢
    • 2014-01-25
    • 1970-01-01
    • 2017-01-08
    • 2014-01-21
    • 2014-03-18
    • 2021-01-23
    • 1970-01-01
    • 1970-01-01
    • 2017-03-19
    相关资源
    最近更新 更多