根据R中的条件创建重复行

Tim*_*cht 9 conditional r duplicates data.table

我有一个看起来像这样的data.table

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

   ID Amount1 Amount2 Dupl
1:  A     100    1500    1
2:  A     200    1500    0
3:  B     300    2400    1
4:  B     400    2400    0
Run Code Online (Sandbox Code Playgroud)

我需要复制Dupl列中包含1的每一行,并将Amount1值替换为该重复行中的Amount2值.除此之外,我需要在Dupl中为重复行提供值2.这意味着它应该如下所示:

   ID Amount1 Amount2 Dupl
1:  A     100    1500    1
2:  A    1500    1500    2
3:  A     200    1500    0
4:  B     300    2400    1
5:  B    2400    2400    2
6:  B     400    2400    0
Run Code Online (Sandbox Code Playgroud)

任何帮助深表感谢!亲切的问候,

蒂姆

akr*_*run 9

你可以试试

rbind(dt,dt[Dupl==1][,c('Amount1', 'Dupl') := list(Amount2, 2)])
Run Code Online (Sandbox Code Playgroud)


zx8*_*754 6

使用dplyr

require("data.table")
require("dplyr")

#data
dt <- data.table(ID=c("A","A","B","B"),Amount1=c(100,200,300,400),
                 Amount2=c(1500,1500,2400,2400),Dupl=c(1,0,1,0))
#result
rbind(dt,
      dt %>% 
        filter(Dupl==1) %>% 
        mutate(Dupl=2,
               Amount1=Amount2))

#    ID Amount1 Amount2 Dupl
# 1:  A     100    1500    1
# 2:  A     200    1500    0
# 3:  B     300    2400    1
# 4:  B     400    2400    0
# 5:  A    1500    1500    2
# 6:  B    2400    2400    2
Run Code Online (Sandbox Code Playgroud)


Jam*_*mes 5

您可以rbind复制已完成正确转换的子集数据:

rbind(dt,copy(dt[Dupl==1])[,Amount1:=Amount2][,Dupl:=Dupl+1])
   ID Amount1 Amount2 Dupl
1:  A     100    1500    1
2:  A     200    1500    0
3:  B     300    2400    1
4:  B     400    2400    0
5:  A    1500    1500    2
6:  B    2400    2400    2
Run Code Online (Sandbox Code Playgroud)

或者,您可以通过子设置获取重复行,然后使用中间步骤转换重复行。这会将重复行保留在原始行旁边,如问题中的示例所示:

x <- dt[rep(seq(dt[,Dupl]),times=dt[,Dupl==1]+1)]
x[duplicated(x),c("Amount1","Dupl"):=list(Amount2,Dupl+1)]
x
   ID Amount1 Amount2 Dupl
1:  A     100    1500    1
2:  A    1500    1500    2
3:  A     200    1500    0
4:  B     300    2400    1
5:  B    2400    2400    2
6:  B     400    2400    0
Run Code Online (Sandbox Code Playgroud)