所以我有一个数据集(这是一个玩具示例(
dates <- c(1,1,1,2,2,2,3,3,3)
dates2 <- c(-1,1,2,-1,1,2, -1, 2,3)
amt <- c(1000, 100, 100, 1000, 100, 100, 1000, 100, 100)
dat <- cbind(dates, dates2, amt)
对于数据帧dat,我需要单独划分amt,但仅限于dates2=-1的情况。所以我会得到一个输出数据帧,比如:
clean
1 1 0.10 (IE 100 / 1000, for row 2)
1 2 0.10
2 1 0.10
2 2 0.10
3 2 0.10
3 3 0.10
有人知道解决这个问题的简单方法吗?(我的大脑现在像糊状物(
更新:
不错,一句话,@Arun的赞美(在下面的评论中(:
DT[, amt := { amt <- amt/amt[dates2 == -1] }, by=dates][dates2 != -1]
或者更简洁地说:
DT[, amt := amt/amt[dates2 == -1], by=dates][dates2 != -1]
原始答案:
library(data.table)
DT <- data.table(dat, key="dates")
# grab "-1" rows, at same time, change col name for simplicity
DT.dates2 <- setnames(DT[dates2==(-1)], "amt", "amt.d")
# remove rows where dates2 == -1
DT <- DT[dates2 != -1]
# divide as required
DT[DT[dates==dates2][DT.dates2], amt := amt / amt.d]
结果:
DT
dates dates2 amt
1: 1 1 0.1
2: 1 2 0.1
3: 2 1 0.1
4: 2 2 0.1
5: 3 2 0.1
6: 3 3 0.1
>
by(dat, dat[1], FUN= function(dfm) {
dfm[ dfm$dates2 != -1, 3] <-dfm[ dfm$dates2!= -1, 3]/dfm[ dfm$dates2== -1, 3]
return(dfm[ dfm$dates2 !=-1 ,]) } )
dates: 1
dates dates2 amt
2 1 1 0.1
3 1 2 0.1
-----------------------------------------------------------------------------
dates: 2
dates dates2 amt
5 2 1 0.1
6 2 2 0.1
-----------------------------------------------------------------------------
dates: 3
dates dates2 amt
8 3 2 0.1
9 3 3 0.1
如果您希望它们再次作为数据帧,则可以使用do.call(rbind, ...)
。