大量组变量:在组内有效地将列数据向上移动一行 [面板数据]

Massive group variables: Move column data ONE ROW UP within the group EFFICIENTLY [Panel data]

小问题:我想将一列中的数据逐组向上移动:在组内,第一行被第二行数据替换,第二行替换为第三等。新列的最后一行是 0。我总共有 40,000 个分组级别和 230,000 行。

长题:我有一个关于消费者购买的面板数据,多个用户多次购买。组变量是具有品牌选择数据的消费者。我想复制一个二选数据来计算同一用户对某个品牌的复购率。定义回购:“第1次购买”的回购为“第2次购买”;而“第2次购买”的回购是“第3次购买”最后一次购买无回购。

我的代码在 r 中完成这个简单的数据操作需要 8 分钟,但在 Excel 中只需要 1 秒。

数据是这样的(按日购物者第一天排序):

    Day Shopper Choice
    1   A   Coke
    2   A   Coke
    1   B   Sprite
    1   C   Coke
    2   C   Pepsi
    3   C   Coke
    1   D   Sprite
    2   D   Sprite

期望的输出:

Day Shopper Choice  choice 2
 1  A   apple        *apple*
 2  A   apple           0
 1  B   Banana          0
 1  C   apple          Banana
 2  C   Banana         apple 
 3  C   apple           0
 1  D   berry           *berry*
 2  D   berry           0

我的原码是

# sort the data by user first and then by day
# choice.2 is the new column name
n<-nrow(dt) 
for (i in 1:n) {
 if (df$shopper[i]==dt$shopper[i+1]) 
{choice.2[i]<-choice[i+1]}
 else {choice.2[i]<-0}}

如果你的意思是你想按购物者分组然后引导 Choice,用零填充,用 dplyr,

library(dplyr)

df %>% group_by(Shopper) %>% mutate(choice2 = lead(as.character(Choice), default = '0'))
## Source: local data frame [8 x 4]
## Groups: Shopper [4]
## 
##     Day Shopper Choice choice2
##   <int>  <fctr> <fctr>   <chr>
## 1     1       A  apple   apple
## 2     2       A  apple       0
## 3     1       B Banana       0
## 4     1       C  apple  Banana
## 5     2       C Banana   apple
## 6     3       C  apple       0
## 7     1       D  berry   berry
## 8     2       D  berry       0 

或 data.table,类似于

library(data.table)

setDT(df)[, choice2 := shift(as.character(Choice), type = 'lead', fill = '0') , by = Shopper][]
##    Day Shopper Choice choice2
## 1:   1       A  apple   apple
## 2:   2       A  apple       0
## 3:   1       B Banana       0
## 4:   1       C  apple  Banana
## 5:   2       C Banana   apple
## 6:   3       C  apple       0
## 7:   1       D  berry   berry
## 8:   2       D  berry       0

或在基地,

df$choice2 <- ave(as.character(df$Choice), df$Shopper, FUN = function(x){c(x[-1], '0')})
df
##   Day Shopper Choice choice2
## 1   1       A  apple   apple
## 2   2       A  apple       0
## 3   1       B Banana       0
## 4   1       C  apple  Banana
## 5   2       C Banana   apple
## 6   3       C  apple       0
## 7   1       D  berry   berry
## 8   2       D  berry       0

如果 Choice 是一个因素,所有版本都会将 choice2 强制转换为角色,这会带来一些时间惩罚。如果将 "0" 添加到因子水平,相同的方法应该无需强制即可工作。