微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

宽到长的正则表达式 R

如何解决宽到长的正则表达式 R

我正在尝试使用 tidyr 将数据从宽格式转换为长格式,但也对其他选项开放。这是具有重复值的假数据集,但它与真实数据集具有相同的结构

structure(list(Category = c("Pre","Pre","post_med_1","post_med_2","post_med_2"
),Time = c(1L,2L,3L,1L,3L),Subj_1_tox = c(4.2,5,2.3,4.2,2.3),Subj_2_tox = c(23L,4L,23L,4L),Subj_3_tox = c(6,4.9,3.2,6,3.2),Subj_1_a1 = c(4.2,Subj_2_a1 = c(23L,Subj_3_a1 = c(6,3.2)),class = "data.frame",row.names = c(NA,-9L))

令我困惑的部分是如何在一次调用中将 tox 列和 a1 列转换为长格式并维护类别和时间列。首先是名称模式的正则表达式。我已经查找了正则表达式模式,但不清楚如何获取它以及如何在 1 次调用中包含 2 个不同的值列?

一次调用基本上就是这样

df_longer<-df %>% 
  pivot_longer(
    cols=contains("tox") & contains("a1"),names_to = c("subject","tox","a1"),names_pattern = "(Subj_['all_numbers') (tox and a1) "
    values_to = c("tox_value","a1"))

最终结果是 Subject(#) 位于名为 subject 的列中,而 tox 值和 a1 值位于其他列中。是否可以在一次通话中完成此操作?我也对其他解决方案持开放态度,但我正在尝试更多地学习 tidyr

最终的结果应该是这样的,但是这个部分的值不对,但其他部分是准确的。

enter image description here

解决方法

您可以将 names_tonames_pattern 用作 -

tidyr::pivot_longer(df,cols = starts_with("Subj"),names_to = c("subject",".value"),names_pattern = "(Subj_\\d+)_(.*)")

#  Category    Time subject   tox    a1
#   <chr>      <int> <chr>   <dbl> <dbl>
# 1 Pre            1 Subj_1    4.2   4.2
# 2 Pre            1 Subj_2   23    23  
# 3 Pre            1 Subj_3    6     6  
# 4 Pre            2 Subj_1    5     5  
# 5 Pre            2 Subj_2    1     1  
# 6 Pre            2 Subj_3    4.9   4.9
# 7 Pre            3 Subj_1    2.3   2.3
# 8 Pre            3 Subj_2    4     4  
# 9 Pre            3 Subj_3    3.2   3.2
#10 post_med_1     1 Subj_1    4.2   4.2
# … with 17 more rows
,

如果我正确理解了您的帖子,那么这可以在一行中实现。请参阅下面的我的解决方案,

# load library;
library(tidyverse)

# Store data;
tmpData <- structure(
                list(
                        Category = c(
                                "Pre","Pre","post_med_1","post_med_2","post_med_2"
                        ),Time = c(1L,2L,3L,1L,3L),Subj_1_tox = c(4.2,5,2.3,4.2,2.3),Subj_2_tox = c(23L,4L,23L,4L),Subj_3_tox = c(6,4.9,3.2,6,3.2),Subj_1_a1 = c(4.2,Subj_2_a1 = c(23L,Subj_3_a1 = c(6,3.2)
                ),class = "data.frame",row.names = c(NA,-9L)
        )

# Pivot longer;
tmpData %>% pivot_longer(cols = contains("Subj"),names_to = "subject")

如果您的列具有共同和不同的前缀,则您不一定需要 regex,就像您需要的所有列都以 Subj 开头的数据一样。因此,您可以使用 contains() 中的 dplyr

如果我误解了您的问题,请告诉我。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。