从R中具有相同ID的行创建新变量(在新列中,但不创建新列)

时间:2018-08-18 09:56:49

标签: r reshape

我想将数据框(左)更改为(右)。 我使用了reshape软件包,但是它将创建新列,而不是我想要创建的

enter image description here

非常感谢您能帮助我解决我的问题!

2 个答案:

答案 0 :(得分:2)

您需要首先创建另一个变量v1v2(对于上面给出的示例数据)。

我们使用aveseq_along创建游程类型id列'idx'。此变量将从1到每组'IDBILL'的观测总数。我们使用paste0添加后缀"v"

(DF <- transform(DF, 
                 idx = ave(IDPRODUCT,
                           IDBILL, # grouping variable
                           FUN = function(x) paste0("v", seq_along(x))
       )))
#  IDBILL IDPRODUCT idx
#1    111    ABC123  v1
#2    111    ABC124  v2
#3    112    BCH134  v1
#4    113    ABC123  v1
#5    113    GDF345  v2

现在使用dcast中的reshape2展开'idx'列并填写'IDPRODUCT'的值。

library(reshape2)
(dcast(DF, IDBILL ~ idx, value.var = 'IDPRODUCT'))
#  IDBILL     v1     v2
#1    111 ABC123 ABC124
#2    112 BCH134   <NA>
#3    113 ABC123 GDF345

如果没有其他软件包,则可以使用reshape代替dcast

reshape(DF, idvar = "IDBILL", timevar = "idx", direction = "wide")

如果您更喜欢data.table,可以尝试

library(data.table)
setDT(DF)[, idx := paste0("v", rleid(IDPRODUCT)), by = IDBILL]
dcast(DF, IDBILL ~ idx, value.var = 'IDPRODUCT')

要最终完成邪恶的三位一体,请尝试tidyverse

library(tidyverse)
DF %>% 
  group_by(IDBILL) %>% 
  mutate(idx = paste0("v", row_number())) %>% 
  spread(idx, IDPRODUCT) %>% 
  ungroup()

数据

DF <- structure(list(IDBILL = c(111, 111, 112, 113, 113), IDPRODUCT = c("ABC123", 
"ABC124", "BCH134", "ABC123", "GDF345")), .Names = c("IDBILL", 
"IDPRODUCT"), row.names = c(NA, -5L), class = "data.frame")

答案 1 :(得分:0)

我希望您也考虑这种解决方案。

数据生成

dt<-data.frame("id"=sample(3,5,replace = TRUE),value=sample(5))
m<-merge(dt, dt) 

然后

IDs<-unique(m[,1])   

i<-1
res<-NULL
while(i<=length(IDs)){

   res<-rbind(res, c(IDs[i],m[m[,1]==IDs[i],2]))
   i<-i+1
}
res

您可以使用rbindrbind.na