簡體   English   中英

如何糾正因子變量水平上的錯誤?

[英]how to correct a mistake made in the levels of a factor variable?

假設我有這個 dataframe

d = data.frame(x = c("1","1 2", "1 3", "2 3", "3", "4"))
d

並且它有變量 x 作為一個因素

d$x = as.factor(d$x)

但是,我發現我編寫的三個關卡中存在錯誤。

所以我想按如下方式替換這些變量的值及其級別:

我想用 1 替換 1 2

我想用 1 替換 1 3

我想用 2 替換 2 3

levels(d$x)

所以我想糾正它。 使用以下方法時:

d$x[which(d$x == "1 2")] <- "1"
d$x[which(d$x == "1 3")] <- "1"
d$x[which(d$x == "2 3")] <- "2"

它創建級別如下

1 1 1 2 3 4

我希望的水平如下

1 2 3 4

我應該怎么做才能處理這個問題? 謝謝

另一種選擇是在修改時返回字符:

d$x <- as.character(d$x)
d$x <- factor(sub(" .+", "", d$x))

d$x
# [1] 1 1 1 2 3 4
# Levels: 1 2 3 4

這個怎么樣? 您將文本按空格分開,然后將列表取消嵌套為長格式。 如果有很多問題,這將起作用。 這還假設有一個空格根據您的示例定義錯誤。

library(tidyverse)

d <-  data.frame(x = c("1","2", "3 4", "5", "6"))

d |>
  mutate(x = str_split(x, pattern = "\\s")) |>
  unnest_longer(x)
#> # A tibble: 6 x 1
#>   x    
#>   <chr>
#> 1 1    
#> 2 2    
#> 3 3    
#> 4 4    
#> 5 5    
#> 6 6

根據評論編輯:這里有兩種方法。 一個使用tidyverse ,一個使用 base R。

library(tidyverse)
  
d <-  data.frame(x = c("1","2", "3 4", "5", "6"))

d |>
  mutate(x = str_remove(x, "\\s4$")) 
#>   x
#> 1 1
#> 2 2
#> 3 3
#> 4 5
#> 5 6

d$x[which(d$x == "3 4")] <- "3"
d
#>   x
#> 1 1
#> 2 2
#> 3 3
#> 4 5
#> 5 6

另一個基於更多信息的編輯:

d = data.frame(x = c("1","1 2", "1 3", "2 3", "3", "4"))

d$x <- as.factor(gsub("(\\d+)\\s\\d+$", "\\1", d$x))

d
#>   x
#> 1 1
#> 2 1
#> 3 1
#> 4 2
#> 5 3
#> 6 4

levels(d$x)
#> [1] "1" "2" "3" "4"

您可以使用fct_collapse

library(dplyr)
library(forcats)
d %>% 
  mutate(x = fct_collapse(x, 
                          "1" = c("1", "1 2", "1 3"),
                          "2" = c("2", "2 3")))
  x
1 1
2 1
3 1
4 2
5 3
6 4

dplyr 中也有專門的dplyr recode()用於此目的:

library(dplyr)

## initial factor
x <- factor(c("1","1 2", "1 3", "2 3", "3", "4"))
levels(x)
#> [1] "1"   "1 2" "1 3" "2 3" "3"   "4"

## edited factor
recode(x, "1 2" = "1", "1 3" = "1", "2 3" = "2")
#> [1] 1 1 1 2 3 4
#> Levels: 1 2 3 4

PS:您不應該以使(以前有效的)答案無效的方式編輯您的問題。

復制對最近一個問題的回答:

在引擎蓋下,一個因子數組是一個帶有標簽(水平)的 integer 數組。 您可以單獨重命名標簽,而無需觸及底層數組。

d = data.frame(x = factor(c("1","1 2", "1 3", "2 3", "3", "4")))
levels(d$x)
[1] "1"   "1 2" "1 3" "2 3" "3"   "4" 

levels(d$x) <- c(1, 1, 1, 2, 3, 4)
levels(d$x)
[1] "1" "2" "3" "4"

d$x
[1] 1 1 1 2 3 4
Levels: 1 2 3 4

如果您有更多級別,並且不想冒險進行手動分配,則可以創建一個替換值字典

d = data.frame(x = factor(c("1","1 2", "1 3", "2 3", "3", "4")))
dict <- setNames(
    gsub(' .$', '', levels(d$x)), # remove spaces and any character after that
    levels(d$x)
)
dict
  1 1 2 1 3 2 3   3   4 
"1" "1" "1" "2" "3" "4" 

然后,您可以使用字典將現有級別標簽替換為新級別標簽

levels(d$x) <- dict[levels(d$x)]
d$x
[1] 1 1 1 2 3 4
Levels: 1 2 3 4

暫無
暫無

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

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