Как закодировать несколько столбцов в порядке и удалить дублирующиеся данные в Tidyverse - PullRequest
2 голосов
/ 01 октября 2019

У меня есть 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 ]

2 голосов
/ 01 октября 2019

Решение с использованием lapply и for-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)
2 голосов
/ 01 октября 2019

Вот один вариант, в котором мы циклически перебираем столбец, преобразуем его в индекс с помощью match, используя значения со значениями unique в этом столбце ('m1'), получая colMaxs (из matrixStats). ), используйте его для добавления к столбцам m1, начиная со 2-го столбца

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>

data

df1 <- structure(list(A1 = c("So,Smith", "Jo, Man", "So,Smith", "Jo, Man", 
"Rose,Moli", "Goli,Gouzo", "Jo, Man", "Rose,Moli", "Goli,Gouzo"
), A2 = c("Amo, Bazse", "Amo, Bazse", "Hosh,Golab", "Jo, Man", 
"Niss, Peak", "Ebi,Sat", "Ebi,Sat", "Niss, Peak", "Jo, Man"), 
    A3 = c("Arzo, Ghas", "Imran, Maz", "Imran, Maz", "Imran, Maz", 
    "Arzo, Ghas", "Imran, Maz", "Imran, Maz", "Arzo, Ghas", "Arzo, Ghas"
    )), class = "data.frame", row.names = c(NA, -9L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...