加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

正则表达式 – 我可以使用tidyr中的separate()或extract()将可变

发布时间:2020-12-14 05:49:17 所属栏目:百科 来源:网络整理
导读:我有一个带有约300个观测值的数据帧,每个观测值与一个数字代码相关联,我希望将其拆分为其组成数字.代码变量是3或4位整数,按其最后一位数对齐,所以我想要的输出看起来像这样: code d4 d3 d2 d1 403 NA 4 0 3 5123 5 1 2 3 105 NA 1 0 5 虽然我可以看到很多方
我有一个带有约300个观测值的数据帧,每个观测值与一个数字代码相关联,我希望将其拆分为其组成数字.代码变量是3或4位整数,按其最后一位数对齐,&所以我想要的输出看起来像这样:

code    d4 d3 d2 d1
 403  <NA>  4  0  3 
5123     5  1  2  3
 105  <NA>  1  0  5

虽然我可以看到很多方法使用strsplit(base R)或stringr :: str_split来划分代码,但是我很难将这些操作应用到我的数据框中.

library(stringr)
as.integer(unlist(str_split(5123,""))[1]) # returns 5,the first digit - correct
as.integer(rev(unlist(str_split(5123,"")))[1]) # returns 3,the last digit - correct

但这似乎是合理的(对我来说)操作

libray(dplyr)
df <- data.frame(code = c(403,5123,105))
df <- df %>% 
  mutate(
    last = as.integer(rev(unlist(str_split(df$code,"")))[4])
  )

回报

> df
  code last
1  403    3
2 5123    3
3  105    3

很明显,我对如何在数据帧中处理列表和原子向量上的操作的理解缺乏…

然后我确信tidyr包中的separate()或extract()函数会有所帮助.当然,如果代码作为字符串提供,每个数字前面有一个前导空格,tidyr :: separate()会产生所需的结果:

library(tidyr)
dfsep <- data.frame(code = c(" 4 0 3","5 1 2 3"," 1 0 5"))
dfsep <- dfsep %>% 
  separate(
    code,c("d4","d3","d2","d1"),fill =  "right",remove = FALSE
    )

dfsep
     code d4 d3 d2 d1
1   4 0 3     4  0  3
2 5 1 2 3  5  1  2  3
3   1 0 5     1  0  5

但是连续的数字串不能以这种方式分割; tidyr :: separate()不支持空搜索模式

df <- data.frame(code = c(403,105))
df <- df %>% 
  separate(
    code,remove = FALSE
  )

df
  code   d4   d3   d2   d1
1  403  403 <NA> <NA> <NA>
2 5123 5123 <NA> <NA> <NA>
3  105  105 <NA> <NA> <NA>

虽然tidyr :: extract()的问题在于虽然它精美地提取了数字,但我还是找不到一组处理3&数字的参数. 4位整数:

dfext <- data.frame(code = c(403,105))
dfext <- dfext %>% 
  extract(
    code,"(.)(.)(.)(.)",remove = FALSE
    ) 

dfext
  code   d4   d3   d2   d1
1  403 <NA> <NA> <NA> <NA>
2 5123    5    1    2    3
3  105 <NA> <NA> <NA> <NA>

也许我还没有理解如何为我的目的构建正确的正则表达式代码…

我已经看过StackOverflow上的相关问题,包括关于separate()的这个问题和关于extract()的这个问题,但是我看不出如何将答案应用到我自己的问题中.问题here给出了具有固定长度值而不是变量值的变量的解决方案.

任何帮助,提示或观察将不胜感激!

附:为了给出背景,这是潜水比赛中潜水的数据框架.每行代表一次潜水,一次观察有多个分组变量:名称,年龄,性别,潜水数量(例如5个中的1个),董事会身高,潜水代码,潜水位置,关税,J1奖励,J2奖励,… J5奖,总奖(最高奖和最低奖),&得分(总奖金乘以关税).代码由FINA确定

解决方法

在使用strsplit分割后,我们可以使用stringi中的stri_list2matrix

n <- max(nchar(df$code)) #get the maximum number of characters
fmt <- paste0('%',n,'d') #create a format for the `sprintf`
library(stringi)
#the list output from `strsplit` can be coerced to `matrix` using
#stri_list2matrix.
d1 <- stri_list2matrix(strsplit(sprintf( fmt,df$code),''),byrow=TRUE)
#But,the output is character class,which we can convert to 'numeric' 
m1 <- matrix(as.numeric(d1),ncol=ncol(d1),nrow=nrow(d1))
m1
#     [,1] [,2] [,3] [,4]
#[1,]   NA    4    0    3
#[2,]    5    1    2    3
#[3,]   NA    1    0    5

对于’dfsep’数据集

v1 <- gsub('s+','',dfsep$code)
n <- max(nchar(v1))
fmt <- paste0('%','s')
d1  <- stri_list2matrix(strsplit(sprintf(fmt,v1),byrow=TRUE)
m1 <- matrix(as.numeric(d1),]   NA    1    0    5

我们可以使用原始数据集进行处理

cbind(dfsep,m1)

这可以成为应用于不同数据集的函数.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读