如何将一列分隔为两列

  • 本文关键字:两列 分隔 一列 r
  • 更新时间 :
  • 英文 :

df <- data.frame(PATIENT_ID=c(1,2,3,4),
                 CODE=c('N18','N180','N190','M1920'))

我想把变量CODE分成两个变量。一个变量显示"CODE"的第一个字母(在我的例子中是"N"或"M"(,另一个显示左边的数字。如果有两个以上的数字,请给出"在第二个数字之后。

输出应为

df <- data.frame(PATIENT_ID=c(1,2,3,4),
                 CODE=c('N18','N180','N190','M1920'),
                 VOR_1=c('N','N','N','M'),
                 VOR_2=c('18','18.0','19.0','19.20'))

最后,将变量"VOR_2"定义为数字变量。

对基本R解决方案使用sub

df$VOR_1 <- sub("^([A-Z]).*$", "\1", df$CODE)
df$VOR_2 <- sub("^([0-9]{2})(?=[0-9])", "\1.", sub("^[A-Z]([0-9]+)$", "\1", df$CODE), perl=TRUE)
df$VOR_2 <- as.numeric(df$VOR_2)    # if desired
df
PATIENT_ID  CODE VOR_1 VOR_2
1          1   N18     N    18
2          2  N180     N  18.0
3          3  N190     N  19.0
4          4 M1920     M 19.20

有必要对VOR_2背后的逻辑进行解释。我们首先使用简单的正则表达式^[A-Z]([0-9]+)$提取从第二个字符开始的所有数字。然后,我们对数字字符串的sub进行第二次调用,在第二个数字后面插入一个小数点。该模式使用正向前瞻,确保只有在三个或更多数字的情况下,点才能相互关联。

通过tidyr使用separate的想法可以是,

library(dplyr)
library(tidyr) #separate
df %>%
     separate(CODE, into = c("text", "num"), sep = "(?<=[A-Za-z])(?=[0-9])") %>%
     mutate(num = as.numeric(num),
            num = num / (10 ^ (nchar(num) - 2))
            )
#  PATIENT_ID text  num
#1          1    N 18.0
#2          2    N 18.0
#3          3    N 19.0
#4          4    M 19.2

您可以使用str_extractsub:

library(stringr)
df$VOR1 <- str_extract(df$CODE, "^[A-Z]") 

在这里,您只需掌握由^标记的字符串开头的大写字母。

df$VOR2 <- sub("(\d{2})(\d{1,2})", "\1.\2", str_extract(df$CODE, "\d+"))

在这里,您首先使用str_extract提取数字,然后在适当的地方插入周期.

结果:

df
  PATIENT_ID  CODE VOR1  VOR2
1          1   N18    N    18
2          2  N180    N  18.0
3          3  N190    N  19.0
4          4 M1920    M 19.20

最新更新