自动且有条件地在现有数据集或数据框上创建新变量

时间:2014-07-22 11:07:49

标签: r dataframe grouping

我有2个数据帧D1& G1并希望根据G1中的值在D1上创建新变量。我是R的新手,所以下面我展示了我目前是如何做的,并且想要一种更有效的方式,因为我知道下面的方法非常基础。

生成df'D1'

的代码
customer <-c("071","072","073","074","075")
grp1 <-c(1,0,0,0,0)
grp2 <-c(1,0,0,0,0)
grp3 <-c(0,1,1,0,0)
grp4 <-c(0,0,1,1,0)
grp5 <-c(0,0,0,0,1)
D1 <- data.frame(customer,grp1,grp2,grp3,grp4,grp5)

D1

  customer grp1 grp2 grp3 grp4 grp5
1  071     1    1    0    0    0
2  072     0    0    1    0    0
3  073     0    0    1    1    0
4  074     0    0    0    1    0
5  075     0    0    0    0    1

生成df'G1'

的代码
Cluster <- c(1,1,2,2,3)
groupname <-c("grp1","grp2","grp3","grp4","grp5")
G1 <- data.frame(Cluster,groupname)

G1

  Cluster groupname
1       1      grp1
2       1      grp2
3       2      grp3
4       2      grp4
5       3      grp5

期望输出的问题:

需要在df'D1'上创建新变量cluster1:3(如下所示),方法是根据落在df'G1'上每个簇中的组名对变量grp1:grp5求和 示例:从df'G1'我们可以看到cluster1 =(grp1 + grp2),因此在df'D1'上,对于cluster1,customer 071的值为2。

  customer grp1 grp2 grp3 grp4 grp5 cluster1 cluster2 cluster3
1      071    1    1    0    0    0        2        0        0
2      072    0    0    1    0    0        0        1        0
3      073    0    0    1    1    0        0        2        0
4      074    0    0    0    1    0        0        1        0
5      075    0    0    0    0    1        0        0        1

目前我一直在使用以下

为每个群集应用公式
D1$cluster1 <- with (D1, grp1+grp2)
D1$cluster2 <- with (D1, grp3+grp4)
D1$cluster3 <- with (D1, grp5)

但实际上我的G1表有60个独特的簇值,所以我需要一个更好更自动的方法来代替60行代码,并且因为落入每个簇的'groupnames'可以改变为不同的通过自动方式设置数据一般会更好。

2 个答案:

答案 0 :(得分:1)

您可以使用split变量上的G1$groupnameD1列进行分组,并返回每行的总和:

cbind(D1,
 lapply(split(as.character(G1$groupname),paste0("Cluster",G1$Cluster)),
   function(x) rowSums(D1[x]) ) 
)

#  customer grp1 grp2 grp3 grp4 grp5 Cluster1 Cluster2 Cluster3
#1      071    1    1    0    0    0        2        0        0
#2      072    0    0    1    0    0        0        1        0
#3      073    0    0    1    1    0        0        2        0
#4      074    0    0    0    1    0        0        1        0
#5      075    0    0    0    0    1        0        0        1

答案 1 :(得分:0)

使用dplyr

 library(dplyr)
 library(tidyr)

 res <- cbind(D1,
 left_join(D1%>%
 gather(groupname, Val, grp1:grp5) ,G1, by="groupname")%>%
 mutate(Cluster=paste0("Cluster",Cluster)) %>%
 group_by(customer, Cluster)%>% summarize(Val=sum(Val)) %>% 
 spread(Cluster, Val) %>% 
 select(-customer))

 res
 #     customer grp1 grp2 grp3 grp4 grp5 Cluster1 Cluster2 Cluster3
 #1      071    1    1    0    0    0        2        0        0
 #2      072    0    0    1    0    0        0        1        0
 #3      073    0    0    1    1    0        0        2        0
 #4      074    0    0    0    1    0        0        1        0
 #5      075    0    0    0    0    1        0        0        1