7

在 R 中,我有 600,000 个分类变量,每个分类变量被分类为“0”、“1”或“2”。

我想做的是折叠“1”和“2”并自行留下“0”,这样在重新分类后“0”=“0”;“1”=“1”和“2”=“1”。最后,我只希望“0”和“1”作为每个变量的类别。

另外,如果可能的话,我宁愿不创建 600,000 个新变量,如果我可以用新值替换现有变量,那就太好了!

最好的方法是什么?

4

7 回答 7

13

我发现这是更通用的使用factor(new.levels[x])

> x <- factor(sample(c("0","1","2"), 10, replace=TRUE)) 
> x
 [1] 0 2 2 2 1 2 2 0 2 1
Levels: 0 1 2
> new.levels<-c(0,1,1)
> x <- factor(new.levels[x])
> x
 [1] 0 1 1 1 1 1 1 0 1 1
Levels: 0 1

新的级别向量必须与 x 中的级别数长度相同,因此您也可以使用字符串和 NA 进行更复杂的重新编码

x <- factor(c("old", "new", NA)[x])
> x
 [1] old    <NA>   <NA>   <NA>   new <NA>   <NA>   old   
 [9] <NA>   new    
Levels: new old
于 2012-01-29T13:43:43.950 回答
10

recode() 有点矫枉过正。您的情况取决于当前的编码方式。假设你的变量是 x。

如果是数字

x <- ifelse(x>1, 1, x)

如果是性格

x <- ifelse(x=='2', '1', x)

如果它是级别 0,1,2 的因子

levels(x) <- c(0,1,1)

这些中的任何一个都可以跨数据框 dta 应用于变量 x 。例如...

 dta$x <- ifelse(dta$x > 1, 1, dta$x)

或者,一个框架的多个列

 df[,c('col1','col2'] <- sapply(df[,c('col1','col2'], FUN = function(x) ifelse(x==0, x, 1))
于 2010-07-16T18:36:21.310 回答
5

recode包中有一个函数car(应用回归的伴侣):

require("car")    
recode(x, "c('1','2')='1'; else='0'")

或者对于您在普通 R 中的情况:

> x <- factor(sample(c("0","1","2"), 10, replace=TRUE))
> x
 [1] 1 1 1 0 1 0 2 0 1 0
Levels: 0 1 2
> factor(pmin(as.numeric(x), 2), labels=c("0","1"))
 [1] 1 1 1 0 1 0 1 0 1 0
Levels: 0 1

更新:要重新编码数据框的所有分类列,tmp您可以使用以下内容

recode_fun <- function(x) factor(pmin(as.numeric(x), 2), labels=c("0","1"))
require("plyr")
catcolwise(recode_fun)(tmp)
于 2010-07-16T17:24:36.933 回答
1

我喜欢 dplyr 中可以快速重新编码值的功能。

 library(dplyr)
 df$x <- recode(df$x, old = "new")

希望这可以帮助 :)

于 2017-06-26T06:55:15.530 回答
0

请注意,如果您只希望结果是 0-1 二元变量,则可以完全放弃因子:

f <- sapply(your.data.frame, is.factor)
your.data.frame[f] <- lapply(your.data.frame[f], function(x) x != "0")

第二行也可以写得更简洁(但可能更神秘)为

your.data.frame[f] <- lapply(your.data.frame[f], `!=`, "0")

这会将您的因素变成一系列逻辑变量,“0”映射到FALSE,其他任何东西都映射到TRUE. FALSE并且TRUE将被大多数代码视为 0 和 1,这反过来在分析中应该给出与使用具有“0”和“1”级别的因子基本相同的结果。事实上,如果它没有给出相同的结果,那就会让人怀疑分析的正确性......

于 2012-01-29T15:28:46.160 回答
0

您可以使用sjmiscrec包的功能,它可以一次重新编码完整的数据帧(假设所有变量至少具有相同的重新编码值)。

library(sjmisc)
mydf <- data.frame(a = sample(0:2, 10, T),
                   b = sample(0:2, 10, T),
                   c = sample(0:2, 10, T))

> mydf
   a b c
1  1 1 0
2  1 0 1
3  0 2 0
4  0 1 0
5  1 0 0
6  2 1 1
7  0 1 1
8  2 1 2
9  1 1 2
10 2 0 1

mydf <- rec(mydf, "0=0; 1,2=1")

   a b c
1  1 1 0
2  1 0 1
3  0 1 0
4  0 1 0
5  1 0 0
6  1 1 1
7  0 1 1
8  1 1 1
9  1 1 1
10 1 0 1
于 2015-06-04T14:30:52.553 回答
0

forcats来自 tidyverse的软件包解决方案

library(forcats)

> x <- factor(sample(c("0","1","2"), 10, replace=TRUE))
> x
[1] 1 1 1 0 1 0 2 0 1 0
Levels: 0 1 2
    
> fct_collapse(x, "1" = c("1", "2"))
[1] 1 1 1 0 1 0 1 0 1 0
Levels: 0 1
于 2021-11-05T18:15:14.120 回答