R 如何根据这些值重新编码数据集?

R 如何根据这些值重新编码数据集?,r,dataframe,R,Dataframe,我有一个大数据集,其格式类似于以下内容: names <- c('s1','s2','s3', 's4', 's5','s6', 's7', 's8','s9') metals <- c(4.2, 5.3, 5.4,6, 7,8.5,0, 10.1,11) plastics <- c(5.1, 0, 2.4,6.1, 7.7,5.5,1.99, 0 ,2.5) grade<- c("AA", "AB", "AB", "AB", "AC" , "AB", NA , NA,

我有一个大数据集,其格式类似于以下内容:

names <- c('s1','s2','s3', 's4', 's5','s6', 's7', 's8','s9')
metals <- c(4.2, 5.3, 5.4,6, 7,8.5,0, 10.1,11)
plastics <- c(5.1, 0, 2.4,6.1, 7.7,5.5,1.99, 0 ,2.5)
grade<- c("AA", "AB", "AB", "AB", "AC" , "AB", NA , NA, NA)
my_df <- data.frame(names, metals, plastics, grade )

names不确定这个是否是最有效的,但是我们可以使用
car
包中的
recode
作为字符列

my_df$metals <- ifelse (my_df$metals > 0, 1 , 0)

my_df$plastics <- ifelse (my_df$plastics > 0, 1 , 0)

library(car)
my_df$grade<-recode(my_df$grade, "'AA'=1; 'AB'='2'; 'AC'='3'")
my_df$metals(0,1,0)
我的_df$plastics(0,1,0)
图书馆(汽车)

my_df$grade不确定这一个是否是最有效的,但我们可以在
car
包中为字符列使用
recode

my_df$metals <- ifelse (my_df$metals > 0, 1 , 0)

my_df$plastics <- ifelse (my_df$plastics > 0, 1 , 0)

library(car)
my_df$grade<-recode(my_df$grade, "'AA'=1; 'AB'='2'; 'AC'='3'")
my_df$metals(0,1,0)
我的_df$plastics(0,1,0)
图书馆(汽车)

my_df$grade对数字列使用
应用
,对字符列使用
匹配

编辑为per@thelatemail的注释,以避免中间矩阵强制

my_df[,sapply(my_df,is.numeric)] = lapply(my_df[,sapply(my_df,is.numeric)],function(x) ifelse(x>0,1,0))

my_df$grade = match(my_df$grade,c("AA","AB","AC"))

my_df
#  names metals plastics grade
#1    s1      1        1     1
#2    s2      1        0     2
#3    s3      1        1     2
#4    s4      1        1     2
#5    s5      1        1     3
#6    s6      1        1     2
#7    s7      0        1    NA
#8    s8      1        0    NA
#9    s9      1        1    NA

不久将有其他使用data.table、dplyr的解决方案。您可以使用
microbenchmark
选择最佳解决方案

使用
apply
选择数字列,使用
match
选择字符列

编辑为per@thelatemail的注释,以避免中间矩阵强制

my_df[,sapply(my_df,is.numeric)] = lapply(my_df[,sapply(my_df,is.numeric)],function(x) ifelse(x>0,1,0))

my_df$grade = match(my_df$grade,c("AA","AB","AC"))

my_df
#  names metals plastics grade
#1    s1      1        1     1
#2    s2      1        0     2
#3    s3      1        1     2
#4    s4      1        1     2
#5    s5      1        1     3
#6    s6      1        1     2
#7    s7      0        1    NA
#8    s8      1        0    NA
#9    s9      1        1    NA

不久将有其他使用data.table、dplyr的解决方案。您可以使用
microbenchmark
从@MFR的答案中选择最佳解决方案,这里有两种方法:

NumColsToReplace = c("metals", "plastics")
my_df[NumColsToReplace] = ifelse(my_df[NumColsToReplace] > 0, 1, 0)
这允许您预先指定要替换的列,而无需多次复制第二行

使用
lappy
replace
还有另一种更有效的方法:

my_df[NumColsToReplace] = lapply(my_df[NumColsToReplace], 
                                 function(x) replace(x, x>0, 1))
这可能需要更多的输入,但速度是第一种方法的两倍(或更多)。以下是一些基准:

Unit: microseconds
                                                                   expr      min
 lapply(my_df[NumColsToReplace], function(x) replace(x, x > 0,      1))     23.949
                                  ifelse(my_df[NumColsToReplace] > 0, 1, 0) 59.445
     lq     mean median     uq     max neval
 26.515 29.92362 28.654 30.364  57.306   100
 62.438 68.84436 63.721 73.129 159.515   100
因此,这取决于数据帧的大小。你想考虑第二种方法。


levels(my_df$grade)与@MFR的答案不符,这里有两种方法:

NumColsToReplace = c("metals", "plastics")
my_df[NumColsToReplace] = ifelse(my_df[NumColsToReplace] > 0, 1, 0)
这允许您预先指定要替换的列,而无需多次复制第二行

使用
lappy
replace
还有另一种更有效的方法:

my_df[NumColsToReplace] = lapply(my_df[NumColsToReplace], 
                                 function(x) replace(x, x>0, 1))
这可能需要更多的输入,但速度是第一种方法的两倍(或更多)。以下是一些基准:

Unit: microseconds
                                                                   expr      min
 lapply(my_df[NumColsToReplace], function(x) replace(x, x > 0,      1))     23.949
                                  ifelse(my_df[NumColsToReplace] > 0, 1, 0) 59.445
     lq     mean median     uq     max neval
 26.515 29.92362 28.654 30.364  57.306   100
 62.438 68.84436 63.721 73.129 159.515   100
因此,这取决于数据帧的大小。你想考虑第二种方法。


levels(my_df$grade)与R中的情况一样,即使是最简单的任务,也有一百万种方法可以完成。这里还有两个:

numvars <- sapply(my_df, is.numeric)
my_df[numvars] <- lapply(my_df[numvars], findInterval, 1)


my_df$grade <- c(2,1,3)[match(my_df$grade, c("AB","AA","AC"))]
               #newvals                    #oldvals

#  names metals plastics grade
#1    s1      1        1     1
#2    s2      1        0     2
#3    s3      1        1     2
#4    s4      1        1     2
#5    s5      1        1     3
#6    s6      1        1     2
#7    s7      0        1    NA
#8    s8      1        0    NA
#9    s9      1        1    NA

numvars在R中,即使是最简单的任务,也有一百万种方法。这里还有两个:

numvars <- sapply(my_df, is.numeric)
my_df[numvars] <- lapply(my_df[numvars], findInterval, 1)


my_df$grade <- c(2,1,3)[match(my_df$grade, c("AB","AA","AC"))]
               #newvals                    #oldvals

#  names metals plastics grade
#1    s1      1        1     1
#2    s2      1        0     2
#3    s3      1        1     2
#4    s4      1        1     2
#5    s5      1        1     3
#6    s6      1        1     2
#7    s7      0        1    NA
#8    s8      1        0    NA
#9    s9      1        1    NA

numvars对于你的第二部分,你也可以只覆盖级别-
levels(my_df$grade)@zheyunali-可能更倾向于将其保留为数字,所以是的,很好。另外,
c(1,2,3)[my_df$grade]
如果我有很多数字列,并且所有的编码模式都相似,我可以一次完成所有的工作吗?@Jack-请参阅下面Osssan的回答和我的评论。我们可以再次使用package car my_df$plastic作为您的第二部分,您也可以覆盖级别-
级别(my_df$grade)@ZheyuanLi-可能更倾向于将其保留为数字,所以是的,很好。另外,
c(1,2,3)[my_-df$grade]
如果我有很多数字列,并且所有的编码模式都相似,我能一次完成所有的工作吗?@Jack-请看下面奥桑的回答和我的评论。我们可以再次使用package car我的_-df$塑料提示-使用
lapply
而不是
应用
-
我的_-df[,sapply(my_-df,is.numeric)]0,1,0))
这将避免对矩阵的强制。谢谢,这很有意义。更新了答案。提示-使用
lappy
而不是
apply
-
my_-df[,sapply(my_-df,is.numeric)]0,1,0]
这将避免对矩阵的强制。谢谢,这很有意义。更新了答案。