我有三个具有某些共同点的因素:如何在所有因素中将相同数字的相等水平改变?

时间:2018-09-02 16:01:06

标签: r factors levels

我已经找到了如何轻松改变因子水平的方法。我的问题是我有三列(因素),它们有一些共同点。我需要确保可以更改-一般而言,因为明年该因子的水平将具有不同的名称-相同“新”水平的因子之间的水平相等。 示例:

> data<-read.table(head=T,"F2_SULMaturação_Conjunta.txt")
> data[25:35,1:5]
   OBS   POP         IDPOP         IDMOM     IDDAD
25  25  MUR3          MUR3 BMXPotênciaRR   M9056RR
26  26  MUR9          MUR9 BMXPotênciaRR   M8221RR
27  27 MUR18         MUR18 BMXPotênciaRR    P98N71
28  28 MUR29         MUR29 BMXPotênciaRR CONQUISTA
29  29 GENIT BMXPotênciaRR             0         0
30  30 GENIT      NA5909RR             0         0
31  31 MUR25         MUR25    DM5958IPRO CONQUISTA
32  32 MUR27         MUR27   TMG7062IPRO CONQUISTA
33  33 GENIT    DM5958IPRO             0         0
34  34 GENIT        P98N71             0         0
35  35  MUR1          MUR1    BMXApoloRR   M9056RR
> levels(data$IDDAD)
[1] "0"         "CONQUISTA" "M8221RR"   "M9056RR"   "P98N71"   
> levels(data$IDMOM)
[1] "0"             "BMXApoloRR"    "BMXPotênciaRR" "DM5958IPRO"    
"DM6563IPRO"   
[6] "NA5909RR"      "TMG7062IPRO"  
> levels(data$IDPOP)
[1] "BMXApoloRR"    "BMXPotênciaRR" "CONQUISTA"     "DM5958IPRO"            
"DM6563IPRO"   
[6] "M8221RR"       "M9056RR"       "MUR1"          "MUR13"         "MUR14"        
[11] "MUR15"         "MUR16"         "MUR17"         "MUR18"         "MUR2"         
[16] "MUR24"         "MUR25"         "MUR26"         "MUR27"         "MUR28"        
[21] "MUR29"         "MUR3"          "MUR7"          "MUR8"          "MUR9"         
[26] "NA5909RR"      "P98N71"        "TMG7062IPRO"  

请注意,某些级别的“ IDPOP”,“ IDMOM”和“ IDDAD”是相同的,即:“BMXPotênciaRR”。 我正在寻找代码,也许可以让我在同一行中设置两个具有各自“新级别”的向量,并进行批量更改。 示例:

> a<-c("BMXPotênciaRR","DM5958IPRO", "TMG7062IPRO")
> b<-c("1","2","3")
> a
[1] "BMXPotênciaRR" "DM5958IPRO"    "TMG7062IPRO"  
> b
[1] "1" "2" "3"

由于我必须以通用方式编写代码,因此我不打算编写级别,而是通过“ levels(...)”捕获它们。

2 个答案:

答案 0 :(得分:0)

如果我们需要在多个列中更改公用levels,请用levels标识公用intersect

# columns of interest
nm1 <- c("IDDAD", "IDMOM", "IDPOP")
v1 <- Reduce(intersect, lapply(data[nm1], levels))

vectorlevels的新级别(可以自定义levels

v2 <- seq_along(v1)

将新的levels分配到列

data[nm1] <- lapply(data[nm1], function(x) {
                   levels(x)[levels(x) %in% v1] <- v2
                    x
                 })

答案 1 :(得分:0)

假设问题在于如何将数据框中所有或指定因子列的级别设置为它们级别的并集。

假设我们有DF(在末尾的注释中显示),其中包含多个因子列和非因子列。

1)基数R 首先计算is.fac是一个逻辑矢量,用于标识哪些列是因子。 (如果您想设置一些因子列,则手动设置is.fac-is.fac可以是每列一个元素的逻辑向量,也可以是要作为索引的列的整数向量已处理或可能是感兴趣的列名称的字符向量。例如,如果我们只考虑前两列,则可以设置is.fac <- 1:2is.fac <- c("A", "B")。)

然后使用Reduce来获取它们的级别levs的并集。如果级别的顺序很重要,则对levs进行排序。

最后将每个因子的水平设置为levs

is.fac <- sapply(DF, is.factor)
levs <- Reduce(union, lapply(DF[is.fac], levels), init = NULL)
fix_levs <- function(x, levs) factor(as.character(x), levels = levs)
DF2 <- replace(DF, is.fac, lapply(DF[is.fac], fix_levs, levs))

我们可以看到因子列的级别相同。例如,请注意,“ {c}”在DF中显示为DF$A中的第三级,在DF$B中显示为第二级,在DF$C中显示为第一级,但是“ c”始终显示在DF2的所有三列中显示为第三级。

DF$A
## [1] a b c
## Levels: a b c
DF$B
## [1] b c d
## Levels: b c d
DF$C
## [1] c d e
## Levels: c d e

DF2$A
## [1] a b c
## Levels: a b c d e
DF2$B
## [1] b c d
## Levels: a b c d e
DF2$C
## [1] c d e
## Levels: a b c d e

2)字符另一种可能性是仅使用字符列。然后,我们不必担心级别是否相同。从上方使用is.fac

DF3 <- replace(DF, is.fac, lapply(DF[is.fac], as.character))

3)forcats 为此目的,forcats软件包具有fct_unify。从上方使用is.fac

library(forcats)
DF4 <- replace(DF, is.fac, fct_unify(DF[is.fac]))

注意

我们使用了以下测试数据框:

DF <- data.frame(A = letters[1:3], B = letters[2:4], C = letters[3:5], D = 1:3)