在一定数量的字符后使用tidyr中的单独分隔列?

问题描述 投票:2回答:3

数据样本:

  Outcome            
  <chr>              
1 X2016-17Denominator
2 X2014-15Denominator
3 X2014-15Outcome    
4 X2010-11Numerator  
5 X2012-13Denominator

我有点不确定如何在sep包提供的separate函数中使用tidyr参数。我仍然是使用正则表达式的新手,但我认为这样的东西会起作用:

sample %<>% separate(Outcome, into=c("date", "metric"), sep="^X[:digit:]{4}[:punct:][:digit:]{2}")

这会使metric列很好,但会将日期列留空。我猜这个问题是被认为是“分隔符”的东西没有被复制,但是我不知道如何在X####-##之后指定字符作为我希望列分隔的字符。

r tidyr stringr
3个回答
2
投票

你可以按位置分开。

library(tidyr)

dat %>%
  separate(Outcome, into=c("date", "metric"), sep = 8)
#       date      metric
# 1 X2016-17 Denominator
# 2 X2014-15 Denominator
# 3 X2014-15     Outcome
# 4 X2010-11   Numerator
# 5 X2012-13 Denominator

数据

dat <- read.table(text = "  Outcome            
1 'X2016-17Denominator'
2 'X2014-15Denominator'
3 'X2014-15Outcome'    
4 'X2010-11Numerator'  
5 'X2012-13Denominator'",
                  header = TRUE, stringsAsFactors = FALSE)

1
投票

separate用于分隔给定分隔符的列(因此您使用正则表达式作为分隔符,因此它只保留metric,因为它认为其余部分应该分隔您的列)。在这种情况下,你应该使用extract

sample = data.frame(Outcome = c(
    'X2016-17Denominator', 
    'X2014-15Denominator',
    'X2014-15Outcome',
    'X2010-11Numerator',
    'X2012-13Denominator'
))

sample %>% 
    extract(
        Outcome, 
        into=c("date", "metric"),
        regex="^X([:digit:]{4}[:punct:][:digit:]{2})(.*)"
    )
#    date      metric
#1 2016-17 Denominator
#2 2014-15 Denominator
#3 2014-15     Outcome
#4 2010-11   Numerator
#5 2012-13 Denominator

1
投票

我们也可以使用separate的正则表达式

library(tidyverse)
df1 %>%
    mutate(Outcome = str_remove(Outcome, "^X")) %>% 
    separate(Outcome, into = c("date", "metric"), sep="(?<=[0-9])(?=[A-Z])")
#     date      metric
#1 2016-17 Denominator
#2 2014-15 Denominator
#3 2014-15     Outcome
#4 2010-11   Numerator
#5 2012-13 Denominator

data

df1 <- structure(list(Outcome = c("X2016-17Denominator", "X2014-15Denominator", 
 "X2014-15Outcome", "X2010-11Numerator", "X2012-13Denominator"
 )), class = "data.frame", row.names = c("1", "2", "3", "4", "5"
 ))
© www.soinside.com 2019 - 2024. All rights reserved.