首页 > 解决方案 > 如何以序列方法对多列进行编码

问题描述

我有多个列,我想按顺序对它们进行编码。这是列的示例:

df<-read.table(text=" A M Z X

124321  33333   123 1309
234543  12121   33  1308
130991  200EE   123 1308
130911  200EE   123 1309
124321  12121   33  1309
234543  33333   232 1309", h=T)

我想得到这张桌子:

df1<-read.table(text=" Group1   Group2  Group3  Group4

1   6   9   12
4   5   8   11
3   7   9   11
2   7   9   12
1   5   8   12
4   6   10  12
", h=T)

我使用了以下基本代码,但它们并不可靠,尤其是当根据我的经验增加列时。

  df$Group1 <- as.integer(as.factor(df$A))
  df$Group2 <- as.integer(as.factor(df$M)) + max(df$Group1)
  df$Group3 <- as.integer(as.factor(df$Z)) + max(df$Group2)
  df$Group4 <- as.integer(as.factor(df$X)) + max(df$Group3)

有没有更好、更可靠的解决方案来获取我的桌子?

标签: rtidyverse

解决方案


您可以使用accumulate

library(tidyverse)

df %>% 
  mutate_all(~ as.integer(as.factor(.))) %>% 
  accumulate(~ .y + max(.x)) %>% 
  bind_cols %>% 
  rename_all(~ paste0('Group', seq_along(.)))

# # A tibble: 6 x 4
#   Group1 Group2 Group3 Group4
#    <int>  <int>  <int>  <int>
# 1      1      7      9     12
# 2      4      5      8     11
# 3      3      6      9     11
# 4      2      6      9     12
# 5      1      5      8     12
# 6      4      7     10     12

第二列与您显示的不同,但根据下面的输出,它看起来像预期的那样工作

df %>% 
  mutate_all(~ as.integer(as.factor(.)))
#   A M Z X
# 1 1 3 2 2
# 2 4 1 1 1
# 3 3 2 2 1
# 4 2 2 2 2
# 5 1 1 1 2
# 6 4 3 3 2

或者,借用 db 的 cumsum/sapply 想法(如果您认为这种方法更好,应该接受 db 的回答)

df %>% 
  mutate_all(~ as.integer(as.factor(.))) %>% 
  map2_dfc(c(0, cumsum(sapply(., max))[-ncol(.)]), `+`)
# # A tibble: 6 x 4
#       A     M     Z     X
#   <dbl> <dbl> <dbl> <dbl>
# 1     1     7     9    12
# 2     4     5     8    11
# 3     3     6     9    11
# 4     2     6     9    12
# 5     1     5     8    12
# 6     4     7    10    12

推荐阅读