如何顺序编码多列并删除tidyverse中的重复数据

时间:2019-10-01 16:58:43

标签: r tidyverse

我有20列,但是这些数据的示例如下:

A1  A2  A3
So,Smith    Amo, Bazse  Arzo, Ghas
Jo, Man Amo, Bazse  Imran, Maz
So,Smith    Hosh,Golab  Imran, Maz
Jo, Man Jo, Man Imran, Maz
Rose,Moli   Niss, Peak  Arzo, Ghas
Goli,Gouzo  Ebi,Sat Imran, Maz
Jo, Man Ebi,Sat Imran, Maz
Rose,Moli   Niss, Peak  Arzo, Ghas
Goli,Gouzo  Jo, Man Arzo, Ghas

我想对从1开始的每一列中的每个人进行编码,因此我将获得以下结果:

A1A A2A A3A
1   5   10
2   5   11
1   6   11
2   7   11
3   8   10
4   9   11
2   9   11
3   8   10
4   7   10

我使用了以下代码:

df$A1A <- as.integer(as.factor(df$A1))
df$A2A <- as.integer(as.factor(df$A2)) + max(df$A1A)
df$A3A <- as.integer(as.factor(df$A3)) + max(df$A2A)

但是有时候我会得到错误的代码,尤其是当列数增加时

最后,我想获得下表。

A1	     C1	   A2	       C2   	A3	      C3
So,Smith	  1  	Amo, Bazse	5	   Arzo, Ghas	10
Jo, Man 	  2	  Hosh,Golab	6	  Imran, Maz	11
Rose,Moli	  3	  Jo, Man	    7		
Goli,Gouzo	4	  Niss, Peak	8		
                Ebi,Sat	    9		

我已使用以下代码删除重复项,但它不起作用。

df[!duplicated(df[c(1:3)]),]

我们可以在R中做到这一点,特别是使用健壮的代码吗?

2 个答案:

答案 0 :(得分:2)

这里是一个选项,其中我们遍历该列,通过match用该列中的unique值('m1')将值转换为索引,得到{{1} }(来自colMaxs),使用它添加从第二列开始的'm1'列

matrixStats

如果我们想获取第二个数据集

m1 <- sapply(df1, function(x) match(x, unique(x)))
library(matrixStats)
v1 <- colMaxs(m1)
#or in base R
# v1 <- apply(m1, 2, max)
m1[,-1] <- m1[,-1] + cumsum(v1[-length(v1)])[col(m1[,-1])]
m1
#      A1 A2 A3
# [1,]  1  5 10
# [2,]  2  5 11
# [3,]  1  6 11
# [4,]  2  7 11
# [5,]  3  8 10
# [6,]  4  9 11
# [7,]  2  9 11
# [8,]  3  8 10
# [9,]  4  7 10

数据

library(rowr)
out <- do.call(cbind.fill, c(Map(function(x, y)
      data.frame(col1 = x, col2 = unique(y)), 
        lapply(df1, unique), split(m1, col(m1))), fill = NA))
names(out) <- c(rbind(names(df1), paste0("C", seq_along(df1))))
out
#          A1   C1         A2 C2         A3   C3
#1   So,Smith    1 Amo, Bazse  5 Arzo, Ghas   10
#2    Jo, Man    2 Hosh,Golab  6 Imran, Maz   11
#3  Rose,Moli    3    Jo, Man  7       <NA> <NA>
#4 Goli,Gouzo    4 Niss, Peak  8       <NA> <NA>
#5       <NA> <NA>    Ebi,Sat  9       <NA> <NA>

答案 1 :(得分:2)

使用lapplyfor-loop的解决方案。

dat2[] <- lapply(dat2, function(x) as.integer(factor(x, levels = unique(x))))

for (i in 1:ncol(dat2)){
  if (i > 1){
    dat2[i] <- dat2[i] + max(dat2[i - 1])
  }
}

dat2
#   A1 A2 A3
# 1  1  5 10
# 2  2  5 11
# 3  1  6 11
# 4  2  7 11
# 5  3  8 10
# 6  4  9 11
# 7  2  9 11
# 8  3  8 10
# 9  4  7 10

数据

dat <- read.table(text = "A1    A2  A3
'So,Smith'  'Amo, Bazse'    'Arzo, Ghas'
'Jo, Man'   'Amo, Bazse'    'Imran, Maz'
'So,Smith'  'Hosh,Golab'    'Imran, Maz'
'Jo, Man'   'Jo, Man'   'Imran, Maz'
'Rose,Moli' 'Niss, Peak'    'Arzo, Ghas'
'Goli,Gouzo'    'Ebi,Sat'   'Imran, Maz'
'Jo, Man'   'Ebi,Sat'   'Imran, Maz'
'Rose,Moli' 'Niss, Peak'    'Arzo, Ghas'
'Goli,Gouzo'    'Jo, Man'   'Arzo, Ghas'",
stringsAsFactors = FALSE, header = TRUE)