R中

2015-11-06 68 views
4

标签独特的价值观我的数据是这样的:R中

data <- matrix(c("1","install","2015-10-23 14:07:20.000000", 
       "2","install","2015-10-23 14:08:20.000000", 
       "3","install","2015-10-23 14:07:25.000000", 
       "3","sale","2015-10-23 14:08:20.000000", 
       "4","install","2015-10-23 14:07:20.000000", 
       "4","sale","2015-10-23 14:09:20.000000", 
       "4","sale","2015-10-23 14:11:20.000000"), 
       ncol=3, byrow=TRUE) 
colnames(data) <- c("id","event","time") 

我想补充的第四列,被称为标签,在标签我相应的每一行上的一些价值观。在这种情况下:

  • “0”的标签,如果ID是唯一
  • “1”的标签,如果ID不是唯一的,它有相关的1个销售
  • “2”的标签,如果id不是唯一的,并且它具有相关联的2个销售

等等最多n个销售。

最后应当是这样的:

data1 <- matrix(c("1","install","2015-10-23 14:07:20.000000","0", 
        "2","install","2015-10-23 14:08:20.000000","0", 
        "3","install","2015-10-23 14:07:25.000000","1", 
        "3","sale","2015-10-23 14:08:20.000000","1", 
        "4","install","2015-10-23 14:07:20.000000","2", 
        "4","sale","2015-10-23 14:09:20.000000","2", 
        "4","sale","2015-10-23 14:11:20.000000","2"), 
       ncol=4, byrow=TRUE) 

这我不清楚什么是R中根据具体的情况来创建“标签”,最好的办法......也许dplyr::mutate

+0

请注意,在您的示例中,您混合了“销售”和“销售”。不知道这是打算还是打字错误。如果您的真实数据是这种情况,那么您应该特别注意这一点。 –

+4

为什么地球上你把这个存储为'矩阵'? – MichaelChirico

回答

4

更新为反映“等到n销售”。 - 要求。

一个dplyr选择是:

library(dplyr) 
data <- as.data.frame(data) 
data %>% 
    group_by(id) %>% 
    mutate(label = if(n() == 1) 0 else as.numeric(sum(event == "sale"))) 

#Source: local data frame [7 x 4] 
#Groups: id [4] 
# 
#  id event      time label 
# (fctr) (fctr)      (fctr) (dbl) 
#1  1 install 2015-10-23 14:07:20.000000  0 
#2  2 install 2015-10-23 14:08:20.000000  0 
#3  3 install 2015-10-23 14:07:25.000000  1 
#4  3 sale 2015-10-23 14:08:20.000000  1 
#5  4 install 2015-10-23 14:07:20.000000  2 
#6  4 sale 2015-10-23 14:09:20.000000  2 
#7  4 sale 2015-10-23 14:11:20.000000  2 

的data.table相当于是:

library(data.table) 
data <- as.data.table(data) # or setDT(data) if it's already a data.frame 
data[, label := if(.N == 1) 0 else as.numeric(sum(event == "sale")), by=id] 
+0

除非我错了,'as.data.frame'不会将所有'character'列转换为'integer' /'numeric',这是您的解决方案所需要的。 – MichaelChirico

+0

@MichaelChirico,不确定你的意思?你能再解释一下吗? –

+0

这段代码很有效,所以downvote被删除了,但这是鼓励糟糕的编程习惯。 – MichaelChirico

4

随着base R

我们可以使用sum通过id使用ave相符的"sale"的发生。然后检查ID是否与uniq一致。我们将"0"分配给任何唯一的行。 cbind将它们放在一起。我也转换为data.frame,因为没有任何理由在矩阵中存储混合信息。

indx <- ave(data[,2], data[,1], FUN=function(x) sum(x == "sale")) 
uniq <- table(data[,1]) == 1 
indx[data[,1] %in% which(uniq)] <- "0" 
cbind.data.frame(data, indx) 
# id event      time count 
# 1 1 sale 2015-10-23 14:07:20.000000  0 
# 2 2 install 2015-10-23 14:08:20.000000  0 
# 3 3 install 2015-10-23 14:07:25.000000  1 
# 4 3 sale 2015-10-23 14:08:20.000000  1 
# 5 4 install 2015-10-23 14:07:20.000000  2 
# 6 4 sale 2015-10-23 14:09:20.000000  2 
# 7 4 sale 2015-10-23 14:11:20.000000  2 
+0

如果data [1,2] ==“sale”'?我认为你再简化太多 –

+0

这是正确的输出。它应该返回第一行的“2”' –

+0

根据“a”0“标签,如果id是唯一的'规则,我会期望第一行为”0“,而不管事件列中的内容。 –

0

与汇总值添加列的另一种dplyr方法是创建汇总在另一个表中变量,然后将其加回到主数据帧中,如下所示:

library(dplyr) 
left_join(data, 
       data %>% 
       group_by(id) %>% 
       summarise(count = n(), sales = sum(event == "sale")) 
) %>% 
    mutate(label = ifelse(count == 1, 0, sales)) %>% 
    select(-count, -sales) 

> data 
    id event      time label 
1 1 install 2015-10-23 14:07:20.000000  0 
2 2 install 2015-10-23 14:08:20.000000  0 
3 3 install 2015-10-23 14:07:25.000000  1 
4 3 sale 2015-10-23 14:08:20.000000  1 
5 4 install 2015-10-23 14:07:20.000000  2 
6 4 sale 2015-10-23 14:09:20.000000  2 
7 4 sale 2015-10-23 14:11:20.000000  2 
+0

如果ID是唯一的,你必须考虑“a”0“标签 –

+0

好的结果,如果OP在数据集中有一行符合条件。更新我的答案来解决这个问题。 –