如何在R中重新编码多个列

如何在R中重新编码多个列,r,R,我尽了最大努力对多个栏目进行重新编码,但我仍然很难做到这一点。以下是我所做的: df<-read.table(text="ZR1 Time1 ZR2 Time2 ZR3 Time3 A 60 A 56 B 44 C 61 B 44 D 78 D 62 C 78 E 66 E 58 D 46 B 45 A 54 B 23 B 23 A 57 E 24 B 100",h=T) 正如你所看到的,我可

我尽了最大努力对多个栏目进行重新编码,但我仍然很难做到这一点。以下是我所做的:

df<-read.table(text="ZR1 Time1 ZR2 Time2 ZR3 Time3
  A 60  A   56  B   44
  C 61  B   44  D   78
  D 62  C   78  E   66
  E 58  D   46  B   45
  A 54  B   23  B   23
  A 57  E   24  B   100",h=T)
正如你所看到的,我可以得到Z1,这是错误的

我想得到这个:

ZR1 Time1   ZR2 Time2   ZR3 Time3   Z1  Z2  Z3
A   60  A   56  B   44  4   4   3
C   61  B   44  D   78  2   3   1
D   62  C   78  E   66  1   2   0
E   58  D   46  B   45  0   1   3
A   54  B   23  B   23  4   3   3
A   57  E   24  B   100 4   0   3
for (i in 1:3) {
  df[[paste0("Z",i)]] <-
    factor(df[[paste0("ZR", i)]],levels=LETTERS[1:5],labels=4:0)
}
df
#   ZR1 Time1 ZR2 Time2 ZR3 Time3 Z1 Z2 Z3
# 1   A    60   A    56   B    44  4  4  3
# 2   C    61   B    44   D    78  2  3  1
# 3   D    62   C    78   E    66  1  2  0
# 4   E    58   D    46   B    45  0  1  3
# 5   A    54   B    23   B    23  4  3  3
# 6   A    57   E    24   B   100  4  0  3

通过使用关卡和标签,您可以获得:

ZR1 Time1   ZR2 Time2   ZR3 Time3   Z1  Z2  Z3
A   60  A   56  B   44  4   4   3
C   61  B   44  D   78  2   3   1
D   62  C   78  E   66  1   2   0
E   58  D   46  B   45  0   1   3
A   54  B   23  B   23  4   3   3
A   57  E   24  B   100 4   0   3
for (i in 1:3) {
  df[[paste0("Z",i)]] <-
    factor(df[[paste0("ZR", i)]],levels=LETTERS[1:5],labels=4:0)
}
df
#   ZR1 Time1 ZR2 Time2 ZR3 Time3 Z1 Z2 Z3
# 1   A    60   A    56   B    44  4  4  3
# 2   C    61   B    44   D    78  2  3  1
# 3   D    62   C    78   E    66  1  2  0
# 4   E    58   D    46   B    45  0  1  3
# 5   A    54   B    23   B    23  4  3  3
# 6   A    57   E    24   B   100  4  0  3
for(1:3中的i){

df[[paste0(“Z”,i)]]通过玩关卡和标签,您可以得到:

ZR1 Time1   ZR2 Time2   ZR3 Time3   Z1  Z2  Z3
A   60  A   56  B   44  4   4   3
C   61  B   44  D   78  2   3   1
D   62  C   78  E   66  1   2   0
E   58  D   46  B   45  0   1   3
A   54  B   23  B   23  4   3   3
A   57  E   24  B   100 4   0   3
for (i in 1:3) {
  df[[paste0("Z",i)]] <-
    factor(df[[paste0("ZR", i)]],levels=LETTERS[1:5],labels=4:0)
}
df
#   ZR1 Time1 ZR2 Time2 ZR3 Time3 Z1 Z2 Z3
# 1   A    60   A    56   B    44  4  4  3
# 2   C    61   B    44   D    78  2  3  1
# 3   D    62   C    78   E    66  1  2  0
# 4   E    58   D    46   B    45  0  1  3
# 5   A    54   B    23   B    23  4  3  3
# 6   A    57   E    24   B   100  4  0  3
for(1:3中的i){

df[[paste0(“Z”,i)]使用
dplyr
+
magrittr
软件包的替代解决方案

library(dplyr); library(magrittr)    
df2 <- select(df, starts_with("ZR")) %>% 
       lapply(as.character) %>% 
       mapply(`[`, list(c(A=4,B=3,C=2,D=1,E=0)), .) %>% 
       data.frame(df, .)
names(df2)[ncol(df2)-2:0] <- paste0("Z", 1:3)
library(dplyr);library(magrittr)
df2%
lapply(作为字符)%>%
映射层(`[`,列表(c(A=4,B=3,c=2,D=1,E=0)),)%>%
数据帧(df)

名称(df2)[ncol(df2)-2:0]使用
dplyr
+
magrittr
包的替代解决方案

library(dplyr); library(magrittr)    
df2 <- select(df, starts_with("ZR")) %>% 
       lapply(as.character) %>% 
       mapply(`[`, list(c(A=4,B=3,C=2,D=1,E=0)), .) %>% 
       data.frame(df, .)
names(df2)[ncol(df2)-2:0] <- paste0("Z", 1:3)
library(dplyr);library(magrittr)
df2%
lapply(作为字符)%>%
映射层(`[`,列表(c(A=4,B=3,c=2,D=1,E=0)),)%>%
数据帧(df)

名称(df2)[ncol(df2)-2:0]这里有一个更类似于dplyr的方法。当输出不是整数时用于重新编码

library(dplyr)
# Make lookup table
lookup <- data.frame(let = LETTERS[1:5], num = 4:0, stringsAsFactors = F)
# Join with lookup table
df %>% 
  left_join(lookup, by = c('ZR1' = 'let')) %>% 
  left_join(lookup, by = c('ZR2' = 'let')) %>% 
  left_join(lookup, by = c('ZR3' = 'let')) %>% 
  rename_at(vars(matches('num')), ~paste0('Z', 1:3))

这里有一个更像dplyr的方法。当输出不是整数时,用于重新编码

library(dplyr)
# Make lookup table
lookup <- data.frame(let = LETTERS[1:5], num = 4:0, stringsAsFactors = F)
# Join with lookup table
df %>% 
  left_join(lookup, by = c('ZR1' = 'let')) %>% 
  left_join(lookup, by = c('ZR2' = 'let')) %>% 
  left_join(lookup, by = c('ZR3' = 'let')) %>% 
  rename_at(vars(matches('num')), ~paste0('Z', 1:3))
这是基本方法(可能也是最快的方法)。您只需使用ZR列的值作为c(A=4,B=3,c=2,D=1,E=0)的索引,c将成为转换表,然后将这些结果分配给df中的新列:

df[ paste0("Z", 1:3) ] <- 
   lapply( df[ , grepl("^ZR", names(df))] , # passes "ZR" columns one-at-a-time 
               function(x) {c(A=4,B=3,C=2,D=1,E=0)[as.character(x)]})
df[paste0(“Z”,1:3)]这是基本方法(可能是最快的方法)。您只需将ZR列的值用作c的索引(A=4,B=3,c=2,D=1,E=0),c将成为转换表,然后将这些结果分配给df中的新列:

df[ paste0("Z", 1:3) ] <- 
   lapply( df[ , grepl("^ZR", names(df))] , # passes "ZR" columns one-at-a-time 
               function(x) {c(A=4,B=3,C=2,D=1,E=0)[as.character(x)]})

df[paste0(“Z”,1:3)]也许这一行加上
dplyr
会有所帮助

df %>% 
  mutate_at(setNames(paste0("ZR", 1:3), paste0("Z", 1:3)), 
            ~5-as.numeric(factor(.x, levels = LETTERS[1:5])))

这里的诀窍是将命名向量传递给
mutate_at
以创建新列。如果预先指定了级别,则可以将factor强制为numeric。

也许使用
dplyr
的这一行可以有所帮助

df %>% 
  mutate_at(setNames(paste0("ZR", 1:3), paste0("Z", 1:3)), 
            ~5-as.numeric(factor(.x, levels = LETTERS[1:5])))

这里的诀窍是将命名向量传递给
mutate_at
以创建新列。如果预先指定了级别,则可以强制因子为数值。

我认为这提供了一个因子向量。可能是也可能不是预期的。我认为这提供了一个因子向量。可能是也可能不是预期的。@42我得到了错误: [.data.table
(x,i,其中=TRUE):我没有使用
数据.table
函数,我认为基函数的屏蔽有问题。您没有指出这是
数据.table
问题。请使用新会话重试。这些是我在没有加载data.table的会话中没有生成的data.table错误。如果我们假设
data.table
已加载,则您有责任在开始时包含代码或调用
库(data.table)
的示例。(但即使我加载
data.table
,我也不会得到那个错误。所以我认为这是因为你运行了另一个答案,强制你的
df
-对象成为data.table。)p.s.@User60你可以用
setDF(df)
类(df)将
data.table
转换回
data.frame
@42我得到了错误:
[.data.table
中的错误(x,I,其中=TRUE):我没有使用
数据.table
函数,我认为基函数的屏蔽有问题。您没有指出这是
数据.table
问题。请使用新会话重试。这些是我在没有加载data.table的会话中没有生成的data.table错误。如果我们假设
data.table
已加载,则您有责任在开始时包含代码或调用
库(data.table)
的示例。(但即使我加载
data.table
,我也不会得到那个错误。所以我认为这是因为你运行了另一个答案,强制你的
df
-对象成为data.table。)p.s.@User60你可以用
setDF(df)
类(df)将
data.table
转换回
data.frame
只想指出失败背后的原因是
stringsAsFactors=TRUE
read.table
中的默认行为(导致因子级别不一致)。这可能就是为什么我们现在可能需要以明确一致的方式使用整洁的数据格式。只想指出失败背后的原因是
stringsAsFactors=TRUE
read.table
中的默认行为(这会导致因子级别不一致).这可能就是为什么我们现在可能需要以明确一致的方式使用整洁的数据格式。