使用dplyr和连接生成唯一ID和组ID

时间:2017-08-29 21:09:16

标签: r crash dplyr

我有一个问题,我怀疑是因为dplyr更新与我的hacky代码相结合而产生的。给定一个数据框,其中每一行都是重复的,我想通过将两列的条目与中间的“_”或“a_”组合来为每一行分配一个唯一的id。我还想通过将一列的条目与“”或“a”组合来分配组ID。由于这些格式对于排列其他数据框架非常重要,因此我无法使用我在其他帖子中看到的基于interactfactor的解决方案。

所以我想离开这个:

   Generation Identity
1           1        X
2           1        Y
3           1        Z
4           2        X
5           2        Y
6           2        Z
7           3        X
8           3        Y
9           3        Z
10          1        X
11          1        Y
12          1        Z
13          2        X
14          2        Y
15          2        Z
16          3        X
17          3        Y
18          3        Z

到此:

   Generation Identity Unique_id Group_id
1           1        X        1_X        X
2           1        Y        1_Y        Y
3           1        Z        1_Z        Z
4           2        X        2_X        X
5           2        Y        2_Y        Y
6           2        Z        2_Z        Z
7           3        X        3_X        X
8           3        Y        3_Y        Y
9           3        Z        3_Z        Z
10          1        X        1a_X        Xa
11          1        Y        1a_Y        Ya
12          1        Z        1a_Z        Za
13          2        X        2a_X        Xa
14          2        Y        2a_Y        Ya
15          2        Z        2a_Z        Za
16          3        X        3a_X        Xa
17          3        Y        3a_Y        Ya
18          3        Z        3a_Z        Za

下面的最小示例基于之前为我和其他人设置唯一ID的代码,但现在导致RStudio崩溃并出现seg错误(异常类型:EXC_BAD_ACCESS(SIGSEGV))。当我调用包含此代码的函数时,它会生成消息

  

匹配错误(vector,df $ Unique_id):'translateCharUTF8'必须是   呼吁CHARSXP

我读过的内容可能是记忆问题的症状。

library(dplyr)
dff <- data.frame(Generation = rep(1:3, each = 3), 
  Identity = rep(LETTERS[24:26], times = 3))
dff <- rbind(dff, dff) # duplicate rows
dff <- group_by_(dff, ~Generation, ~Identity) %>% 
  mutate(Unique_id = c(paste0(Identity[1], "_", Generation[1]), paste0(Identity[1], "a", "_", Generation[1]))) %>% 
  ungroup

我认为问题与dplyr的更新有关(我正在使用最新版本的RStudio和所有软件包,在OSX Sierra上)。无论如何,我上面的解决方案是一种破解。我非常感谢有关改进代码的建议,最好使用base R或dplyr(因为代码是当前依赖于dplyr的包的一部分)。

2 个答案:

答案 0 :(得分:0)

以下是解决问题的方法:

首先找到您的数据的副本。我调用了我的数据A

 dup=duplicated(A)

然后添加一个计数器行:

 A$count=1:nrow(A)
n=ncol(A)#THE COLUMN ADDED

现在获取所需的两列并使用原始数据框cbind:

     B=data.frame(t(apply(A,1,function(x)
        if(dup[as.numeric(x[n])]) c(paste0(x["Identity"],"a"),paste(x[-n],collapse="a_")) 
        else c(x["Identity"],paste(x[-n],collapse="_")))))

  `names<-`(cbind(A[-n],B),c(names(A[-1]),"Group_ID","Unique_ID"))
    Identity count Group_ID Unique_ID
 1         1     X        X       1_X
 2         1     Y        Y       1_Y
 3         1     Z        Z       1_Z
 4         2     X        X       2_X
 5         2     Y        Y       2_Y
 6         2     Z        Z       2_Z
 7         3     X        X       3_X
 8         3     Y        Y       3_Y
 9         3     Z        Z       3_Z
 10        1     X       Xa      1a_X
 11        1     Y       Ya      1a_Y
 12        1     Z       Za      1a_Z
 13        2     X       Xa      2a_X
 14        2     Y       Ya      2a_Y
 15        2     Z       Za      2a_Z
 16        3     X       Xa      3a_X
 17        3     Y       Ya      3a_Y
 18        3     Z       Za      3a_Z

答案 1 :(得分:0)

这是我对Onyambu解决方案的修订版本,它按名称而不是数字引用列(因此可以处理具有其他列的数据框):

dup <- duplicated(dff) # identify duplicates
dff$count <- 1:nrow(dff) # add count column to the dataframe

# create a new dataframe containing the unique and group ids:
B <- data.frame(t(apply(dff, 1, function(x)
  if(dup[as.numeric(x["count"])]) c(paste0(x["Identity"], "a"), 
  paste(x["Identity"], x["Generation"], sep = "a_")) 
  else c(x["Identity"], paste(x["Identity"], x["Generation"], sep = "_")))))

# combine the dataframes:
colnames(B) <- c("Group_id", "Unique_id")
dff <- cbind(dff[-ncol(dff), B)