【问题标题】:One-Hot-Coding for factors defined through several columns?One-Hot-Encoding 通过几列定义的因素?
【发布时间】:2021-05-21 12:30:40
【问题描述】:

我正在为科学期刊尝试不同的聚类方法,并且我有一个具有这种结构的数据框:

'data.frame':   30883 obs. of  11 variables:
 $ Title        : chr  "CA - A Cancer Journal for Clinicians" "MMWR. Recommendations and reports : Morbidity and mortality weekly report. Recommendations and reports / Centers for Disease Co"| __truncated__ "Nature Reviews Materials" "Quarterly Journal of Economics" ...
 $ ISSN1        : chr  "15424863" "10575987" "20588437" "00335533" ...
 $ ISSN2        : chr  "00079235" "15458601" NA "15314650" ...
 $ SubCat1      : chr  "Hematology" "Epidemiology" "Biomaterials" "Economics and Econometrics " ...
 $ SubCat2      : chr  "Oncology " "Health Information Management" "Electronic, Optical and Magnetic Materials" NA ...
 $ SubCat3      : chr  NA "Health social science" "Energy" NA ...
 $ SubCat4      : chr  NA "Health, Toxicology and Mutagenesis" "Materials Chemistry" NA ...
 $ SubCat5      : chr  NA "Medicine " "Surfaces, Coatings and Films " NA ...
 $ SubCat6      : chr  NA NA NA NA ...
 $ Top.Level    : chr  "Health Sciences" "Health Sciences" "Physical Sciences and Engineering" "Social Sciences and Humanities" ...
 $ Primary.Level: chr  NA NA NA NA ...

我的问题是 SubCat 列中的元素没有特定的顺序,这意味着例如 Oncology 可能出现在这 6 个列中的任何一个列中,尽管尽管列号是相同的类别。例如,假设 SubCat1 有 136 个不同的术语,但其中 80 个与具有 240 个不同术语的 SubCat4 相同。总体而言,两列的水平高达 136+240-80 个不同的因素。

我想对所有 6 个 SubCat 列进行 1 热编码,因此我为所有 6 个 SubCat 列中的每个不同因素都有一个列(无论它是否出现在多个列中,我都想要一个列)。我试图避免通过 for 和 dplyr 操作手动对所有内容进行编程,但到目前为止,我还没有找到任何简单的方法(我通常最终将所有六列合并为每列 1hotcod,这意味着很多重复的列)。

有什么优雅的方法可以解决这个问题吗?也许我在问一些明显的问题,但我还没有找到它......

谢谢

编辑:这里有一些在“肿瘤学”中有重复的行:

dput(p[1:10, ])
structure(list(Title = c("Cancer Treatment Reviews", "npj Breast Cancer", 
"Journal of Thoracic Oncology", "International Journal of Radiation Oncology Biology Physics", 
"Radiotherapy and Oncology", "Prostate Cancer and Prostatic Diseases", 
"Oral Oncology", "Lung Cancer", "Annals of Surgical Oncology", 
"Frontiers in Oncology"), ISSN1 = c("03057372", "23744677", "15561380", 
"03603016", "18790887", "13657852", "18790593", "01695002", "10689265", 
"2234943X"), ISSN2 = c(NA, NA, "15560864", "1879355X", "01678140", 
"14765608", "13688375", "18728332", "15344681", NA), SubCat1 = c("Medicine", 
"Oncology", "Medicine", "Cancer Research", "Hematology", "Cancer Research", 
"Cancer Research", "Cancer Research", "Oncology", "Oncology"), 
    SubCat2 = c("Oncology", "Pharmacology medical", "Oncology", 
    "Oncology", "Oncology", "Oncology", "Oncology", "Oncology", 
    "Surgery ", "Cancer Research 2"), SubCat3 = c("Radiology, Nuclear Medicine and Imaging ", 
    "Radiology, Nuclear Medicine and Imaging ", "Pulmonary and Respiratory Medicine ", 
    "Radiation", "Radiology, Nuclear Medicine and Imaging ", 
    "Urology ", "Oral Surgery ", "Pulmonary and Respiratory Medicine ", 
    NA, NA), SubCat4 = c(NA, NA, NA, "Radiology, Nuclear Medicine and Imaging ", 
    NA, NA, NA, NA, NA, NA), SubCat5 = c(NA_character_, NA_character_, 
    NA_character_, NA_character_, NA_character_, NA_character_, 
    NA_character_, NA_character_, NA_character_, NA_character_
    ), SubCat6 = c(NA_character_, NA_character_, NA_character_, 
    NA_character_, NA_character_, NA_character_, NA_character_, 
    NA_character_, NA_character_, NA_character_), Top.Level = c("Health Sciences", 
    "Health Sciences", "Health Sciences", "Health Sciences", 
    "Health Sciences", "Health Sciences", "Health Sciences", 
    "Health Sciences", "Health Sciences", "Health Sciences"), 
    Primary.Level = c("Medicine and Dentistry", NA, NA, "Medicine and Dentistry", 
    NA, NA, NA, "Medicine and Dentistry", NA, NA)), .Names = c("Title", 
"ISSN1", "ISSN2", "SubCat1", "SubCat2", "SubCat3", "SubCat4", 
"SubCat5", "SubCat6", "Top.Level", "Primary.Level"), row.names = c("469", 
"493", "590", "1208", "1316", "1535", "1718", "1769", "1856", 
"1867"), class = "data.frame")

【问题讨论】:

  • str() 对于理解数据的结构非常有用,但对于为我们提供示例数据并无帮助。您能否找到几行(不超过 10 行)来说明问题,即它们在不同的子目录列中有一些重叠的元素,并以可复制粘贴的方式共享这些数据? dput() 制作 R 对象的复制/粘贴版本:dput(your_data[selected_rows, ]).

标签: r dataframe dplyr multiple-columns one-hot-encoding


【解决方案1】:

您可以使用pivot_longer 将您的猫放入一列,然后使用pivot_wider 及其values_fnvalues_fill 参数来计算各个类别,而不会丢失其他列:

library(tidyverse)
(df <- tibble(Title = letters[1:10],
              ISSN = sample(10000000,10),
              SubCat1 = factor(LETTERS[1:10]),
              SubCat2 = factor(LETTERS[11:20]))
)
#> # A tibble: 10 x 4
#>    Title    ISSN SubCat1 SubCat2
#>    <chr>   <int> <fct>   <fct>  
#>  1 a     7361068 A       K      
#>  2 b     7988851 B       L      
#>  3 c     8771863 C       M      
#>  4 d      146888 D       N      
#>  5 e     9104811 E       O      
#>  6 f     3612300 F       P      
#>  7 g     3242950 G       Q      
#>  8 h     1225062 H       R      
#>  9 i     6462332 I       S      
#> 10 j     7363583 J       T

atLeastOne <- function(x){
    ifelse(length(x) > 0,
           1,
           0)
  }
  
  df %>% 
    pivot_longer(matches('SubCat'),
                 names_to = 'subcat',
                 values_to = 'category') %>% 
    pivot_wider(names_from = 'category',
                values_from = 'subcat',
                values_fn = atLeastOne,
                values_fill = 0)
#> # A tibble: 10 x 22
#>    Title    ISSN     A     K     B     L     C     M     D     N     E     O
#>    <chr>   <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
#>  1 a     7361068     1     1     0     0     0     0     0     0     0     0
#>  2 b     7988851     0     0     1     1     0     0     0     0     0     0
#>  3 c     8771863     0     0     0     0     1     1     0     0     0     0
#>  4 d      146888     0     0     0     0     0     0     1     1     0     0
#>  5 e     9104811     0     0     0     0     0     0     0     0     1     1
#>  6 f     3612300     0     0     0     0     0     0     0     0     0     0
#>  7 g     3242950     0     0     0     0     0     0     0     0     0     0
#>  8 h     1225062     0     0     0     0     0     0     0     0     0     0
#>  9 i     6462332     0     0     0     0     0     0     0     0     0     0
#> 10 j     7363583     0     0     0     0     0     0     0     0     0     0
#> # … with 10 more variables: F <int>, P <int>, G <int>, Q <int>, H <int>,
#> #   R <int>, I <int>, S <int>, J <int>, T <int>

【讨论】:

  • 谢谢!我会试试看是否适合我。我在数据中看到的唯一区别是列中的值重复(ej,第一列 ABDC 第二列 AFGC,加上我有很多 NA,因为每个期刊只有少数类别,但我可能可以解决 NA。
  • 名声应该没问题。最好在 ifelse 函数的第一个参数中添加 &amp; !is.na(X) 以应对 NA
【解决方案2】:

抱歉,我确定我在问一些显而易见的问题,但是当我应用建议的代码时,它在控制台上运行良好,但之后结果不会存储在 df 中。我的意思是,控制台输出是这样的(我想要的):

# A tibble: 29,407 x 1,082
   Title    ISSN1  ISSN2  Top.Level Primary.Level Hematology `Oncology `  None Epidemiology `Health Informa…
   <chr>    <chr>  <chr>  <fct>     <chr>              <dbl>       <dbl> <dbl>        <dbl>            <dbl>
 1 CA - A … 15424… 00079… Health S… NA                     1           1     1            0                0
 2 MMWR. R… 10575… 15458… Health S… NA                     0           0     1            1                1
 3 Nature … 20588… NA     Physical… NA                     0           0     1            0                0
 4 Quarter… 00335… 15314… Social S… NA                     0           0     1            0                0
 5 Nature … 14710… 14710… Health S… NA                     0           0     1            0                0
 6 Nationa… 15518… 15518… Social S… NA                     0           0     1            0                0
 7 Nature … 14710… 14710… Health S… NA                     0           0     1            0                0
 8 Cell     00928… 10974… Life Sci… Biochemistry…          0           0     1            0                0

但 df 在环境中仍然只显示 11 列。此外,如果我写 df[1,] 我得到:

df[1,]
                                 Title    ISSN1    ISSN2    SubCat1   SubCat2 SubCat3 SubCat4 SubCat5
1 CA - A Cancer Journal for Clinicians 15424863 00079235 Hematology Oncology     None    None    None
  SubCat6       Top.Level Primary.Level
1    None Health Sciences          <NA>

但是如果我使用 dput(df[1,]) 我得到了整个东西(1082 列)。 难道我做错了什么?应用代码后,df 里面到底是什么?我的计划是根据 SubCat 列对行进行聚类,所以我需要以某种方式将它们传递给算法,但我不能像 df[i,]

那样引用它们

很抱歉,如果这很明显,但它从未发生在我身上。 感谢您的帮助!

【讨论】:

  • 抱歉,我已经解决了。我猜是 %>% 的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
  • 2021-11-02
  • 1970-01-01
  • 1970-01-01
  • 2019-10-11
相关资源
最近更新 更多