如何将一列分成多列并将结果从字符更改为数字

时间:2018-06-28 12:10:27

标签: r filter tidyverse

enter image description here

## id ## ## initiativen ##

1 abc 2a 2 cde 2b 3 EFD 4个 5吉达5v 6 jydjytd e

你好,我有一个与此类似的东西,只是更大了一点,我想知道哪种方法是将原始列分为两列的最有效方法,一列包含数字(2,2,5,4),一列包含字母或空格。它必须是一个通用公式,因为我也需要应用它的数据框很大。字母对应于特定的起始编号,但未显示第一个起始编号,“ a”对应于起始编号2。

我希望它看起来像用数字代替字母的东西(空白= 1,a = 2,b = 3等)

id    initiativen question
abc        2         2
cde        3         2
efd        2         N/A
geh        4         N/A
jytd       23        5
jydjytd    6         N/A
bfdhslbf   1         3

我尝试使用“分隔”,但是它实际上没有用,也不能解决没有相应字母的第一个倡议的问题。 任何帮助或建议都将受到极大的欢迎和帮助。

非常感谢您:)

3 个答案:

答案 0 :(得分:1)

下面的tidyverse解决方案如何?

library(tidyverse);
df %>%
    separate(initiativen, into = c("p1", "p2"), sep = "(?<=[0-9])(?=[a-z])") %>%
    mutate(
        initiativen = case_when(
            str_detect(p1, "[a-z]") ~ p1,
            str_detect(p2, "[a-z]") ~ p2),
        question = case_when(
            str_detect(p1, "[0-9]") ~ p1,
            str_detect(p2, "[0-9]") ~ p2)) %>%
    mutate(initiativen = ifelse(is.na(initiativen), 1, match(initiativen, letters) + 1)) %>%
    select(-p1, -p2)
#       id initiativen question
#1     abc           2        2
#2     cde           3        2
#3     efd           2     <NA>
#4     geh           4     <NA>
#5    jytd          23        5
#6 jydjytd           6     <NA>
#7 vbdjfkb           1        4

请注意,警告separate产生时,由于缺少字段,因此可以安全地忽略该警告。

说明:我们使用正向后看和前瞻性将initiativen中的条目分为p1p2两部分;然后,我们使用initiativenquestion中的条目填充p1p2,具体取决于它们是包含数字"[0-9]"还是字符"[a-z]";用match(initiativen, letters)将字符转换为数字,最后清理data.frame


样本数据

df <- read.table(text =
    "       id initiativen
1     abc          2a
2     cde          2b
3     efd           a
4     geh           c
5    jytd          5v
6 jydjytd           e
7 vbdjfkb          4", row.names = 1)

答案 1 :(得分:0)

使用data.table

# Step one
    setDT(df)
df[, ":="(
      question  = gsub("[a-z]", "", initiativen),
      initiativen = match(gsub("[0-9]", "", initiativen), letters, nomatch = 0) + 1L
    )
   ]
df
        id initiativen question
1:     abc           2        2
2:     cde           3        2
3:     efd           2         
4:     geh           4         
5:    jytd          23        5
6: jydjytd           6         
7: vbdjfkb           1        4

# Then some tidying
df[, question := ifelse(nzchar(question), question, NA)]

df
        id initiativen question
1:     abc           2        2
2:     cde           3        2
3:     efd           2     <NA>
4:     geh           4     <NA>
5:    jytd          23        5
6: jydjytd           6     <NA>
7: vbdjfkb           1        4

数据

df <- data.frame(
  id = c("abc", "cde", "efd", "geh", "jytd", "jydjytd", "vbdjfkb"),
  initiativen = c("2a", "2b", "a", "c", "5v", "e", "4"),
  stringsAsFactors = FALSE
)

修改

也可以一步完成:

df[, question := gsub("[a-z]", "", initiativen)
   ][, ":="(
      question = ifelse(nzchar(question), question, NA),
      initiativen = match(gsub("[0-9]", "", initiativen), letters, nomatch = 0) + 1L
    )
   ]

答案 2 :(得分:0)

对于第二列,您可以使用正则表达式仅保留数字值:

df$initiativen <- gsub("[^0-9]", "", df$initiativen)