表。对于此数据表,我有一个余额列,我想根据余额列中的更改创建一列。 模拟数据
set.seed(1)
zzz <- data.table(name=rep(c('x','y','z'),100),
balance=sample(100:300,100,replace = T), key = "name")
现在我已经改变了一些数据来模拟我想要做的事情
zzz[5:7,2] <-238
zzz[20:22,2]<- 204
因为我想为了展示我打算实现的目标而做出一些平衡,
现在我的代码为每个名称的平衡更改获得一个标志如下
cur_bal <- -99999999
bal_change_flag <- function(x){
#cur_bal <- -99999999
flag <- 1
if(x !=cur_bal){
flag <- 1
}else {flag <- 0}
cur_bal <<-x
return (flag)
}
zzz[,code:=lapply(balance,bal_change_flag),name]
现在我希望zzz[5:7,2:3,with=F]
为
balance code
1: 238 1
2: 238 0
3: 238 0
但我明白了
balance code
1: 238 1
2: 238 1
3: 238 1
如果我不按名称对它进行分组,但是当我按名称对它进行分组时,该功能无法正常工作。请告知:)谢谢
> zzz[,code:=lapply(balance,bal_change_flag)]
> zzz[5:7,2:3,with=F]
balance code
1: 238 1
2: 238 0
3: 238 0
答案 0 :(得分:3)
我不确定你要做的是什么,但我想你是在尝试为每行中的余额是否发生变化创建一个标志?
我认为你做了一个糟糕的例子。也许这更好:
set.seed(3040)
data <- data.table(name = rep(c("x","y","z"), 100),
balance = sample(3, 100, TRUE), key = "name")
我认为你所追求的就像:
data[ , code := balance == shift(balance, fill = TRUE), by = name]
输出:
> data
name balance code
1: x 2 TRUE #first obs. within group always TRUE thanks to 'fill'
2: x 3 TRUE #3 != 2
3: x 1 TRUE #1 != 3
4: x 1 FALSE #1 == 1
5: x 2 TRUE
---
296: z 3 TRUE
297: z 3 FALSE
298: z 2 TRUE
299: z 1 TRUE
300: z 1 FALSE
您可以使用1
或0
强制执行as.integer
和+
,但为什么?
答案 1 :(得分:1)
在我看来,Dplyr更直观,更容易。在这里使用它,你可以做这样的事情:
library(dplyr)
> zzz <- data.frame(name=rep(c('x','y','z'),100),balance=sample(100:300,100,replace = T))
> zzz <- arrange(zzz, name)
> zzz[5:7,2] <-238
> zzz[20:22,2]<- 204
> zzz <- zzz %>% group_by(name) %>% mutate(code = as.numeric(balance != lag(balance)))
> zzz[5:7, ]
Source: local data frame [3 x 3]
Groups: name [1]
name balance code
(fctr) (dbl) (dbl)
1 x 238 1
2 x 238 0
3 x 238 0
> zzz[20:22, ]
Source: local data frame [3 x 3]
Groups: name [1]
name balance code
(fctr) (dbl) (dbl)
1 x 204 1
2 x 204 0
3 x 204 0
>