根据R中行的条件分类创建指标列

时间:2015-06-15 10:24:45

标签: r

我有这样的数据集:

user.id  user_type
3          old
3          old
4          new
5          new
5          new
6          old

我想创建一个新列,表明user_type第一次是' new'对于每个user_id。

输出应如下所示:

user.id  user_type  indicator
3          old         2
3          old         2
4          new         1
5          new         1
5          new         2
6          old         2

我使用了转换功能,但它无效,我的代码:

input <- transform(input, user =
ifelse(head(user_type) == "NEW", 1, 2))

2 个答案:

答案 0 :(得分:2)

我们可以使用其中一个聚合函数。使用data.table,我们会转换&#39; data.frame&#39;到&#39; data.table&#39; (setDT(input)),按&#39; user.id&#39;分组,我们创建一个&#39;指标&#39;通过检查&#39; user_type&#39;中的元素来变量这是&#39; new&#39; (user_type=='new')同时满足第一次观察((1:.N)==1L))的条件,否定它(!)改变“真实”。到了&#39; FALSE&#39;反之,加1(即1L),使TRUE转换为2,FALSE转换为1.

library(data.table)
setDT(input)[,indicator:= (!((user_type=='new') & (1:.N)==1L))+1L, by= user.id]
#     user.id user_type indicator
#1:       3       old         2
#2:       3       old         2
#3:       4       new         1
#4:       5       new         1
#5:       5       new         2
#6:       6       old         2

或者使用dplyr,我们按&#39; user.id&#39;分组,使用mutate和{{1}创建新列(&#39;指标&#39;) }。

ifelse

修改

我之前认为如果新的&#39; value是&#39; user_type&#39;的第一个元素。对于每个“user.id&#39;”,它应该是&#39; 1&#39;否则&#39; 2&#39;。如果OP希望获得&#39; 1&#39;这是第一次&#39; new&#39;每个用户都会出现这样的情况。而不是基于第一行。

library(dplyr)
input %>% 
    group_by(user.id) %>% 
    mutate(indicator= ifelse(user_type =='new' & row_number()==1L , 1, 2))
#   user.id user_type indicator
#1       3       old         2
#2       3       old         2
#3       4       new         1
#4       5       new         1
#5       5       new         2
#6       6       old         2

如果我们更改了&#39; user_type&#39; as&#39; new&#39;第二次观察

  setDT(input)[, indicator:= (!(user_type=='new'& 
                 !duplicated(user_type)))+1L , user.id]
  #   user.id user_type indicator
  #1:       3       old         2
  #2:       3       old         2
  #3:       4       new         1
  #4:       5       new         1
  #5:       5       new         2
  #6:       6       old         2

使用 input$user_type[2] <- 'new' setDT(input)[, indicator:= (!(user_type=='new'& !duplicated(user_type)))+1L , user.id] # user.id user_type indicator #1: 3 old 2 #2: 3 new 1 #3: 4 new 1 #4: 5 new 1 #5: 5 new 2 #6: 6 old 2

dplyr

数据

  input %>% 
     group_by(user.id) %>% 
     mutate(indicator= ifelse(user_type=='new'&!duplicated(user_type), 1, 2))

答案 1 :(得分:2)

另一种data.table方法

library(data.table)
indx <- setDT(df)[, .I[match("new", user_type)], by = user.id]$V1
df[indx, indicator := 1L][is.na(indicator), indicator := 2]
#    user.id user_type indicator
# 1:       3       old         2
# 2:       3       old         2
# 3:       4       new         1
# 4:       5       new         1
# 5:       5       new         2
# 6:       6       old         2