我有一个大数据集,其格式类似于以下内容:
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 )
我需要重新编码每一列对于数字列,我需要指定1,其中值大于0,对于“等级”列,我们假设我想要AA = 1,AB = 2,AC = 3。最有效的方法是什么?
谢谢!
答案 0 :(得分:2)
与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
答案 1 :(得分:1)
不确定这个是否最有效,但我们可以在recode
包中使用car
作为字符列。
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'")
输出
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>
答案 2 :(得分:1)
将apply
用于数字列,将match
用于字符列
编辑以避免中间矩阵强制
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
选择最佳解决方案
答案 3 :(得分:0)
关于@ MFR的回答,这里有两种方法:
NumColsToReplace = c("metals", "plastics")
my_df[NumColsToReplace] = ifelse(my_df[NumColsToReplace] > 0, 1, 0)
这允许您预先指定要替换的列,而无需多次复制第二行。
使用lapply
和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) <- c(1,2,3)
重新编码@thelatemail提到的等级似乎是效率最高的。