Перекодировать столбец на основе двух других векторов - PullRequest
1 голос
/ 17 июня 2019

Это мой набор данных:

df = structure(list(from = c(0, 0, 0, 0, 38, 43, 49, 54), to = c(43, 
54, 56, 62, 62, 62, 62, 62), count = c(342, 181, 194, 386, 200, 
480, 214, 176), group = c("keiner", "keiner", "keiner", "keiner", 
"paid", "paid", "owned", "earned")), class = c("tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -8L))

Моя проблема в том, что столбцы from и to должны быть ранжированы (ранжирование должно быть сделано для двух столбцов from и to), поскольку библиотека визуализации требует этого, а также должна начать с индекса 0. Вот почему я строю два вектора, один (ranking) с ранжированием каждого уникального значения двух столбцов, другой (uniquevalues) с оригинальными уникальными значениями набора данных.

ranking <- dplyr::dense_rank(unique(c(df$from, df$to))) - 1 ### Start Index at 0, "recode" variables
uniquevalues <- unique(c(df$from, df$to))

Теперь я должен перекодировать исходный набор данных. Столбцы to и from должны получать значения от ranking в соответствии с соответствующим значением uniquevalues.

Единственный вариант, с которым я столкнулся, - это создание кадра данных двух векторов и цикл по каждой строке, но мне бы очень хотелось иметь векторизованное решение для этого. Кто-нибудь может мне помочь?

Это:

  <dbl> <dbl> <dbl> <chr> 
1     0    43   342 keiner
2     0    54   181 keiner
3     0    56   194 keiner
4     0    62   386 keiner
5    38    62   200 paid  
6    43    62   480 paid  
7    49    62   214 owned 
8    54    62   176 earned

должно стать таким:

   from    to count group 
  <dbl> <dbl> <dbl> <chr> 
1     0     2   342 keiner
2     0     4   181 keiner
3     0     5   194 keiner
4     0     6   386 keiner
5     1     6   200 paid  
6     2     6   480 paid  
7     3     6   214 owned 
8     4     6   176 earned

Ответы [ 3 ]

3 голосов
/ 17 июня 2019

Мы могли бы unlist значения и match их с помощью uniquevalues

df[1:2] <- match(unlist(df[1:2]), uniquevalues) - 1

df

#   from    to count group 
#  <dbl> <dbl> <dbl> <chr> 
#1     0     2   342 keiner
#2     0     4   181 keiner
#3     0     5   194 keiner
#4     0     6   386 keiner
#5     1     6   200 paid  
#6     2     6   480 paid  
#7     3     6   214 owned 
#8     4     6   176 earned

Или использовать имена столбцов вместо индекса.

df[c("from", "to")] <- match(unlist(df[c("from", "to")]), uniquevalues) - 1
2 голосов
/ 17 июня 2019

Еще одно решение, конвертирующее в фактор и обратно.

f <- unique(unlist(df1[1:2]))

df[1:2] <- lapply(df[1:2], function(x) {
  as.integer(as.character(factor(x, levels=f, labels=1:length(f) - 1)))
  })
df
# # A tibble: 8 x 4
#  from    to  count group 
# <fct> <fct> <dbl> <chr> 
# 1   0     2    342 keiner
# 2   0     4    181 keiner
# 3   0     5    194 keiner
# 4   0     6    386 keiner
# 5   1     6    200 paid  
# 6   2     6    480 paid  
# 7   3     6    214 owned 
# 8   4     6    176 earned
1 голос
/ 17 июня 2019

Я бы использовал mapvalues функцию.Как это

library(plyr)
df[ , 1:2] <- mapvalues(unlist(df[ , 1:2]),
                        from= uniquevalues,
                        to= ranking)
df
#   from    to count group 
#  <dbl> <dbl> <dbl> <chr> 
#1     0     2   342 keiner
#2     0     4   181 keiner
#3     0     5   194 keiner
#4     0     6   386 keiner
#5     1     6   200 paid  
#6     2     6   480 paid  
#7     3     6   214 owned 
#8     4     6   176 earned
...