根据其他列值创建列

时间:2014-11-11 05:04:08

标签: r

我的数据看起来像以下格式。 我想要做的是添加新列,这是用户的主要出口位置。主要位置是用户购买最大金额的位置。示例user2从3个网点购买,outlet2的总购买量= 14,Outlet3 = 34,Outlet4 = 26。因此user2的主要位置是" Outlet 003"


  • ID位置金额
  • 1 Outlet001 11
  • 2 Outlet002 14
  • 2 Outlet003 18
  • 2 Outlet003 16
  • 2 Outlet004 26
  • 3 Outlet002 19
  • 3 Outlet004 15
  • 6 Outlet003 15
  • 7 Outlet003 23
  • 7 Outlet004 12
  • 8 Outlet003 31
  • 8 Outlet003 34
  • 9 Outlet001 14
  • 9 Outlet001 31
  • 9 Outlet003 30
  • 9 Outlet004 19

3 个答案:

答案 0 :(得分:1)

使用data.table

 library(data.table)
 setDT(df)[, Amount1:=sum(Amount), by=list(ID, Location)][,
             mainoutlet:=Location[which.max(Amount1)], by=ID][, Amount1:=NULL]

 df
 #   ID  Location Amount mainoutlet
 #1:  1 Outlet001     11  Outlet001
 #2:  2 Outlet002     14  Outlet003
 #3:  2 Outlet003     18  Outlet003
 #4:  2 Outlet003     16  Outlet003
 #5:  2 Outlet004     26  Outlet003
 #6:  3 Outlet002     19  Outlet002
 #7:  3 Outlet004     15  Outlet002
 #8:  6 Outlet003     15  Outlet003
 #9:  7 Outlet003     23  Outlet003
#10:  7 Outlet004     12  Outlet003
#11:  8 Outlet003     31  Outlet003
#12:  8 Outlet003     34  Outlet003
#13:  9 Outlet001     14  Outlet001
#14:  9 Outlet001     31  Outlet001
#15:  9 Outlet003     30  Outlet001
#16:  9 Outlet004     19  Outlet001

数据

 df <- structure(list(ID = c(1L, 2L, 2L, 2L, 2L, 3L, 3L, 6L, 7L, 7L, 
 8L, 8L, 9L, 9L, 9L, 9L), Location = c("Outlet001", "Outlet002", 
 "Outlet003", "Outlet003", "Outlet004", "Outlet002", "Outlet004", 
 "Outlet003", "Outlet003", "Outlet004", "Outlet003", "Outlet003", 
 "Outlet001", "Outlet001", "Outlet003", "Outlet004"), Amount = c(11L, 
 14L, 18L, 16L, 26L, 19L, 15L, 15L, 23L, 12L, 31L, 34L, 14L, 31L, 
 30L, 19L)), .Names = c("ID", "Location", "Amount"), class = "data.frame",
 row.names = c(NA, -16L))

答案 1 :(得分:1)

这是一个dplyr选项,可以补充其他答案:

require(dplyr)
df %>%
  group_by(ID, MainOutlet = Location) %>%
  summarise(total = sum(Amount)) %>%
  summarise(MainOutlet = MainOutlet[which.max(total)]) %>%
  left_join(df, ., by = "ID")
#   ID  Location Amount MainOutlet
#1   1 Outlet001     11  Outlet001
#2   2 Outlet002     14  Outlet003
#3   2 Outlet003     18  Outlet003
#4   2 Outlet003     16  Outlet003
#5   2 Outlet004     26  Outlet003
#6   3 Outlet002     19  Outlet002
#7   3 Outlet004     15  Outlet002
#8   6 Outlet003     15  Outlet003
#9   7 Outlet003     23  Outlet003
#10  7 Outlet004     12  Outlet003
#11  8 Outlet003     31  Outlet003
#12  8 Outlet003     34  Outlet003
#13  9 Outlet001     14  Outlet001
#14  9 Outlet001     31  Outlet001
#15  9 Outlet003     30  Outlet001
#16  9 Outlet004     19  Outlet001

简要说明:首先需要按ID location进行分组,以便计算每个ID和位置的总金额。通过使用summarise,分组变量的最后一层(在本例中为Location)将被剥离,这意味着,在第一个summarise之后,数据仅按{{1}分组}}。然后,我们可以继续将数据减少到仅具有每个ID的最大销售量(在第二个ID中)的那些位置,并且该结果(每个ID仅1行)基于加入原始数据框summarise

答案 2 :(得分:0)

这可能不是最好/最快的方式,但这就是我所拥有的:

首先,我只使用了一部分数据集来节省时间。

ID = c(1,2,2,2,2,3,3,6,7,7)
Location = c("Outlet001","Outlet002","Outlet003","Outlet003", "Outlet004",
             "Outlet002", "Outlet004", "Outlet003", "Outlet003",
             "Outlet003")
Amount = c(11,14,18,16,26,19,15,15,23,12)  

df = data.frame("ID"=ID, "Location"=Location, "Amount"=Amount)

然后我使用了函数&#39; ddply&#39;来自包装&#39; plyr&#39;创建2个新数据集:&#39; df2&#39;它告诉您给定用户的每个位置的总花费和&#39; df3&#39;它给出了相应的Main条目(用户花费最多的Outlet)。

library(plyr)
df2 = ddply(df, .(ID, Location), summarize,
            Amount = sum(Amount))
df3 = ddply(df2, "ID", transform,
              Location = Location,
              Main = Location[which.max(Amount)])

然后我使用merge函数创建我认为你正在寻找的数据框:

 df4 = merge(df,df3, by.x = c("ID", "Location"), by.y = c("ID","Location"))

输出如下:

    > df4
   ID  Location Amount.x Amount.y      Main
1   1 Outlet001       11       11 Outlet001
2   2 Outlet002       14       14 Outlet003
3   2 Outlet003       18       34 Outlet003
4   2 Outlet003       16       34 Outlet003
5   2 Outlet004       26       26 Outlet003
6   3 Outlet002       19       19 Outlet002
7   3 Outlet004       15       15 Outlet002
8   6 Outlet003       15       15 Outlet003
9   7 Outlet003       23       35 Outlet003
10  7 Outlet003       12       35 Outlet003

请注意,我没有重新标记新的&#39;总数&#39;所以在合并之后,总数由列'Amount.y&#39;表示。 (Amount.x是原始(df)集中列出的数量)。