簡體   English   中英

如何根據值重新編碼數據集?

[英]How to recode dataset based on the values?

我有一個大數據集,其格式類似於以下內容:

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。 最有效的方法是什么?

謝謝!

與R中一樣,有百萬種方法可以完成最簡單的任務。 這里還有2個:

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

不確定這是否是最有效的一種,但是我們可以使用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'")

產量

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>

使用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)

這使您可以預先指定要替換的列,而不必多次復制第二行。

還有一種使用lapplyreplace更有效的方法:

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提到的等級似乎是最有效的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM