如何在巨大的data.frame中使用函数将具有字符值的几列转换为二进制数字?

时间:2019-04-09 19:45:34

标签: r

我有一个巨大的data.frame,其中包含数字,字符和缺失值。如何在保留缺失值的同时将所有“ True”和“ False”(字符值)转换为1和0?

我尝试使用dplyr recode函数,但不适用于类data.frame的对象。

df <- data.frame(Var1 = 150:154 , Var2 = c("True","True","","False","True"), 
Var3 = c("","True","True","False","True"), 
Var4 = 1116:1120, Var99 = c("","True","","False","True"))
> df
  Var1  Var2  Var3 Var4 Var99
1  150  True       1116      
2  151  True  True 1117  True
3  152        True 1118      
4  153 False False 1119 False
5  154  True  True 1120  True

,我的输出将是:

> df2
  Var1 Var2 Var3 Var4 Var99
1  150    1      1116      
2  151    1    1 1117     1
3  152         1 1118      
4  153    0    0 1119     0
5  154    1    1 1120     1

4 个答案:

答案 0 :(得分:2)

您可以使用dplyr函数mutate_ifcase_when。为简单起见,在创建data.frame时将stringAsFactors设置为FALSE。

df <- data.frame(Var1 = 150:154 , Var2 = c("True","True","","False","True"), 
                 Var3 = c("","True","True","False","True"), 
                 Var4 = 1116:1120, Var99 = c("","True","","False","True"), stringsAsFactors = FALSE)

df %>% 
    mutate_if(is.character, ~case_when(. == "True" ~ 1L, 
                                       . == "False" ~ 0L, 
                                       . == "" ~ NA_integer_))

答案 1 :(得分:2)

使用as.logicalas.numeric的基本R方法:

> df[c("Var2", "Var3", "Var99")] <- lapply(df[c("Var2", "Var3", "Var99")], function(x){
+   as.numeric(as.logical(x))
+ })
> df
  Var1 Var2 Var3 Var4 Var99
1  150    1   NA 1116    NA
2  151    1    1 1117     1
3  152   NA    1 1118    NA
4  153    0    0 1119     0
5  154    1    1 1120     1

另外,就像@IceCreamToucan所说的那样,如果您不想键入易记名称,请使用:

> vars_logic <- sapply(df, function(x) {all(x %in% c('True', 'False', ''))})
> 
> df[vars_logic] <- lapply(df[vars_logic], function(x){
+   as.numeric(as.logical(x))
+ })
> 
> df
  Var1 Var2 Var3 Var4 Var99
1  150    1   NA 1116    NA
2  151    1    1 1117     1
3  152   NA    1 1118    NA
4  153    0    0 1119     0
5  154    1    1 1120     1

答案 2 :(得分:1)

一个选项为mutate_if,并使用fct_recode中的forcats将值重新编码为1,0

library(dplyr)
library(forcats)
df %>% 
   mutate_if(is.factor, list(~ fct_recode(.,  "1" = "True", "0" = "False" )))
#    Var1 Var2 Var3 Var4 Var99
#1  150    1      1116      
#2  151    1    1 1117     1
#3  152         1 1118      
#4  153    0    0 1119     0
#5  154    1    1 1120     1

注意:列不是逻辑(TRUE/FALSE),而是(True/False)。因此,保持数据集对象不变且没有任何其他假设

注意2:转换后不会更改列类型


要更改为数字,可以使用match

df %>%
     mutate_if(is.factor,  list( ~ match(., c("False", "True")) - 1))

答案 3 :(得分:1)

考虑到所有具有True / False的列都是因素,您可以尝试此dplyr解决方案(但是,也请查看@akrun提供的注释):

df %>%
 mutate_if(is.factor, list(~ as.logical(.) * 1))

  Var1 Var2 Var3 Var4 Var99
1  150    1   NA 1116    NA
2  151    1    1 1117     1
3  152   NA    1 1118    NA
4  153    0    0 1119     0
5  154    1    1 1120     1

或者根据@Santiago Capobianco的想法进行一些修改:

df %>%
 mutate_if(is.factor, list(~ as.numeric(as.logical(.))))