簡體   English   中英

R-將每個字母因子的字母數字字符觀測值拆分為列,並為每個觀測值分配數值

[英]R - split alphanumeric char observations with column for each letter factor with value of numeric for each observation

我不太確定如何最好地用標題表達我想做的事情。

我有一個看起來像這樣的數據框:

 ID = c(1, 2, 3, 4, 5, 6, 7)
 observation = c("a2", NA, "b3", "c5", NA, "b", "a3")
 df <- data.frame(cbind(ID, observation))

 df

  ID observation
1  1          a2
2  2        <NA>
3  3          b3
4  4          c5
5  5        <NA>
6  6           b
7  7          a3

我想要的輸出是一個數據框架,該數據框架將觀察值按數字和字母進行拆分,每個唯一字母都有一個新列,其中每一行都包含該字母的關聯觀察值。

所需的輸出應如下所示:

desired_df <- data.frame(cbind(ID, a = c(2, NA, 0, 0, 0 , 0, 3), 
                                   b = c(0, NA, 3, 0, 0, 0, 0),
                                   c = c(0, NA, 0, 5, 0, 0, 0)))
desired_df

  ID  a  b  c
1  1  2  0  0
2  2 NA NA NA
3  3  0  3  0
4  4  0  0  5
5  5  0 NA NA
6  6  0  0  0
7  7  3  0  0

我嘗試通過將觀察結果分為帶有正則表達式的字母和數字並將結果保存到新列中來解決此問題:

library(stringr)
char <- unlist(str_replace_all(observation, "[[:digit:]]", ""))
num <- unlist(str_extract(observation, "[[:digit:]]"))
df_new <- cbind(ID, char, num)
df_new

  ID char  num
1  1    a    2
2  2 <NA> <NA>
3  3    b    3
4  4    c    5
5  5 <NA> <NA>
6  6    b <NA>
7  7    a    3

然后嘗試根據此SO問題的答案將char轉換為因子成二進制形式

df_new <- data.frame(cbind(df, sapply(levels(as.factor((char))), 
function(x) as.integer(x == char))))

  ID char  num  a  b  c
1  1    a    2  1  0  0
2  2 <NA> <NA> NA NA NA
3  3    b    3  0  1  0
4  4    c    5  0  0  1
5  5 <NA> <NA> NA NA NA
6  6    b <NA>  0  1  0
7  7    a    3  1  0  0

然后,我根據此SO問題的答案,嘗試用df_new1 $ num中該行的相應值替換每個1觀察值:

df_new2 <- data.frame(with(df_new1, ifelse(df_new1 == 1, df_new1$num, 0)))

df_new2
  ID char num  a  b  c
1  1    0   0  1  0  0
2  0   NA  NA NA NA NA
3  0    0   0  0  2  0
4  0    0   0  0  0  3
5  0   NA  NA NA NA NA
6  0    0  NA  0 NA  0
7  0    0   0  2  0  0

輸出錯誤的結果。 我一直在努力解決這個問題。 我可以將所有非1值替換為0,只要a,b,c列中的值正確即可。

我不確定是否將字母和數字分成不同的列,並嘗試將字母的二進制觀測值替換為因子甚至是嘗試解決我的原始問題的最佳方法,並且對任何可行的方法都持開放態度。

我的真實數據幀是由一個腳本生成的,該腳本從.txt文件中提取模式,其中字母數字的觀察值隨文件的不同而不同。 我需要一些對分配給char列的唯一字母起作用的東西。

我是R的新手,因此感謝您提出的任何建議或幫助。我仍然非常熟悉SO禮節,並且希望對如何改善問題和/或可復制的示例提出任何意見。

您可以使用tidyr extract tidyrobservation分為varvalue列,然后使用spread調整表的tidyr 請注意,由於ID == 2中的NA值, <NA>現在是其自己的列。 select將刪除該列:

library(dplyr)
library(tidyr)

df %>%
  extract(observation, c("var", "value"), regex = "([a-z])?(\\d)?") %>%
  spread(var, value) %>%
  select(-`<NA>`)

結果:

  ID    a    b    c
1  1    2 <NA> <NA>
2  2 <NA> <NA> <NA>
3  3 <NA>    3 <NA>
4  4 <NA> <NA>    5
5  5 <NA> <NA> <NA>
6  6    3 <NA> <NA>

既然您提到非數字值可以為0NA

library(tidyverse)
df %>%
  nest(-ID) %>%
  mutate(data = map(data, ~data.frame(key = gsub("\\d", "", unlist(.x)), val = gsub("\\D", "", unlist(.x))))) %>%
  unnest() %>%
  spread(key, val, fill = 0) %>%
  select(-ncol(.)) %>%
  replace(.=="", 0)

  # ID    a     b     c    
  # <fct> <chr> <chr> <chr>
# 1 1     2     0     0    
# 2 2     0     0     0    
# 3 3     0     3     0    
# 4 4     0     0     5    
# 5 5     0     0     0    
# 6 6     3     0     0    
# There were 14 warnings (use warnings() to see them)    

暫無
暫無

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

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