我有三个共同的因素:如何在所有因素中改变相同数字的相同水平?

问题描述 投票:0回答:2

我已经找到了如何以一种简单的方式改变因子的水平。我的问题是我有三个列(因子),它们有一些共同的水平。我需要确定我可以改变 - 一般来说,因为明年这个因素的水平将有不同的名称 - 相同的“新”水平的因素水平相等。例:

> 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"

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

r factors levels
2个回答
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
                 })

0
投票

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

假设我们有几个因子和非因子列的DF(在最后的注释中显示)。

1)Base 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))

我们可以看到因子列的级别是相同的。例如,请注意,“q”在DF中出现为DF$A中的第3级,DF$B中的第2级和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)
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.