基于R data.table中另一列的更改在数据表中创建列

基于R data.table中另一列的更改在数据表中创建列,r,data.table,R,Data.table,表。对于此数据表,我有一列用于平衡,我想根据平衡列中的更改创建一列。 模拟数据 set.seed(1) zzz <- data.table(name=rep(c('x','y','z'),100), balance=sample(100:300,100,replace = T), key = "name") 但我得到的是 balance code 1: 238 1 2: 238 1 3: 238 1

表。对于此数据表,我有一列用于平衡,我想根据平衡列中的更改创建一列。 模拟数据

set.seed(1)
zzz  <- data.table(name=rep(c('x','y','z'),100),
                   balance=sample(100:300,100,replace = T), key = "name")
但我得到的是

   balance code
1:     238    1
2:     238    1
3:     238    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
> 
库(dplyr)
>ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
>zzz[5:7,]
来源:本地数据帧[3 x 3]
分组:名称[1]
姓名余额代码
(fctr)(dbl)(dbl)
1 x 238 1
2x2380
3 x 238 0
>zzz[20:22,]
来源:本地数据帧[3 x 3]
分组:名称[1]
姓名余额代码
(fctr)(dbl)(dbl)
1 x 204 1
2x204 0
3 x 204 0
> 

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
> 
库(dplyr)
>ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
>zzz[5:7,]
来源:本地数据帧[3 x 3]
分组:名称[1]
姓名余额代码
(fctr)(dbl)(dbl)
1 x 238 1
2x2380
3 x 238 0
>zzz[20:22,]
来源:本地数据帧[3 x 3]
分组:名称[1]
姓名余额代码
(fctr)(dbl)(dbl)
1 x 204 1
2x204 0
3 x 204 0
> 

我不确定您想做什么,但我猜您想创建一个标志,显示每行的余额是否发生了变化

我认为你树立了一个糟糕的榜样。也许这样更好:

set.seed(3040)
data <- data.table(name = rep(c("x","y","z"), 100),
                   balance = sample(3, 100, TRUE), key = "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

您可以通过使用
as.integer
+
将其强制为
1
0
,但为什么呢?

我不知道您想做什么,但我想您是想创建一个标志,显示每行的余额是否发生了变化

我认为你树立了一个糟糕的榜样。也许这样更好:

set.seed(3040)
data <- data.table(name = rep(c("x","y","z"), 100),
                   balance = sample(3, 100, TRUE), key = "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

你可以通过使用
as.integer
+
强制将其设置为
1
0
,但是为什么呢?

+1,我从来没有使用过dplyr,必须学习它,这就是为什么我更喜欢使用data.table方法的soln:)感谢Nevertheleshi如何将每组的第一个条目设置为1,例如,在这篇文章中,我希望第一个as 1不是NA
1 x 153 NA 2 x 282 1 3 x 289 1 4 x 112 1 5 x 238 1 6 x 238 0 7 x 238 0 8 x 142 1。整数更好而不是
为.numeric
。尝试一下
+(平衡!=lag(平衡))
为你的生活增添一些情趣;-)@Bg1850:您可以通过将NAs替换为1来改变值。zzz$code[is.na(zzz$code)]是的,我添加这一行是为了实现这一
%%>%mutate(flag_change=ifelse(is.na(flag_change),1,flag_change)
+1,我从未使用过dplyr,必须学习它,这就是为什么我更喜欢使用数据表方法的soln:)谢谢Nevertheleshi,我如何将每组的第一个条目设为1,例如,在这篇文章中,我希望第一个as 1不是NA
1 x 153 NA 2 x 282 1 3 x 289 1 4 x 112 1 5 x 238 1 6 x 238 0 7 x 238 0 8 x 142 1。整数更好而不是
为.numeric
。尝试一下
+(平衡!=lag(平衡))
为你的生活增添一些情趣;-)@Bg1850:您可以通过将NAs替换为1来改变值。zzz$code[is.na(zzz$code)]是的,我添加了这一行来实现这个
%%>%mutate(flag\u change=ifelse(is.na(flag\u change),1,flag\u change)
感谢您提供了很好的示例和答案,是的,您是正确的,我制作了一个很差的示例,但这是我当时提出的最好的示例,我需要将其设置为1,0,因为我要将其存储在维表中,这便于数值计算。感谢您耐心地理解我的问题,并感谢您的支持answer@Bg1850无论何时这是必需的,它将自动强制为整数。请参见
?TRUE::Details
,但是任何一种方式都可以。知道函数在分组时不起作用的原因吗?虽然我已经用提供的解决方案解决了问题,但这将困扰我,除非我得到解释。感谢伟大的示例和答案,是的,你是正确的我举了一个很差的例子,但这是我当时提出的最好的例子,我需要这个1,0,因为我将把它存储在一个维表中,便于数值计算answer@Bg1850只要需要,它就会自动强制为整数。请参阅
?TRUE::Details
这两种方法都可以。尽管我已经用提供的解决方案解决了问题,但如果我没有得到解释,你知道为什么分组时该函数不起作用吗。
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