当前位置: 首页 > 知识库问答 >
问题:

将多组测量列(宽格式)重塑为单列(长格式)

萧阳波
2023-03-14

我有一个宽格式的数据框,在不同的日期范围内进行重复测量。在我的示例中,有三个不同的周期,都有相应的值。例如,第一个测量值(Value1)是在从DateRange1StartDateRange1End的周期内测量的:

ID DateRange1Start DateRange1End Value1 DateRange2Start DateRange2End Value2 DateRange3Start DateRange3End Value3
1 1/1/90 3/1/90 4.4 4/5/91 6/7/91 6.2 5/5/95 6/6/96 3.3 

我希望将数据重塑为长格式,以便对DateRangeXStart和DateRangeXEnd列进行分组,。因此,原始表中的1行变成了新表中的3行:

ID DateRangeStart DateRangeEnd Value
1 1/1/90 3/1/90 4.4
1 4/5/91 6/7/91 6.2
1 5/5/95 6/6/96 3.3

我知道必须有一个方法来做到这一点与reshape2//重铸/tidyr,但我似乎无法弄清楚如何映射多组测量变量到单组值列以这种特殊的方式。

共有3个答案

严瑞
2023-03-14

从版本1.0.0起,使用tidyr包的函数pivot\u longer()可以将具有多个值/度量值列的宽格式重塑为长格式。

这优于之前的tidyr策略,即聚集(gather(),而不是扩散(请参阅@AndrewMacDonald的答案),因为属性不再被删除(在下面的示例中,日期仍然是日期,数字仍然是数字)。

library("tidyr")
library("magrittr")

a <- structure(list(ID = 1L, 
                    DateRange1Start = structure(7305, class = "Date"), 
                    DateRange1End = structure(7307, class = "Date"), 
                    Value1 = 4.4, 
                    DateRange2Start = structure(7793, class = "Date"),
                    DateRange2End = structure(7856, class = "Date"), 
                    Value2 = 6.2, 
                    DateRange3Start = structure(9255, class = "Date"), 
                    DateRange3End = structure(9653, class = "Date"), 
                    Value3 = 3.3),
               row.names = c(NA, -1L), class = c("tbl_df", "tbl", "data.frame"))

pivot_longer()(对应:pivot_wider())的工作原理类似于Collection()。但是,它提供了额外的功能,例如多个值列。只有一个值列,宽数据集的所有冒名将进入一个长列,名称在names_to中给出。对于多个值列,names_to可能会接收多个新名称。

如果所有列名都遵循特定的模式,例如Start\u 1End\u 1Start\u 2等,那么这是最简单的。因此,我在第一步中重命名了这些列。

(names(a) <- sub("(\\d)(\\w*)", "\\2_\\1", names(a)))
#>  [1] "ID"               "DateRangeStart_1" "DateRangeEnd_1"  
#>  [4] "Value_1"          "DateRangeStart_2" "DateRangeEnd_2"  
#>  [7] "Value_2"          "DateRangeStart_3" "DateRangeEnd_3"  
#> [10] "Value_3"

pivot_longer(a, 
             cols = -ID, 
             names_to = c(".value", "group"),
             # names_prefix = "DateRange",
             names_sep = "_")
#> # A tibble: 3 x 5
#>      ID group DateRangeEnd DateRangeStart Value
#>   <int> <chr> <date>       <date>         <dbl>
#> 1     1 1     1990-01-03   1990-01-01       4.4
#> 2     1 2     1991-07-06   1991-05-04       6.2
#> 3     1 3     1996-06-06   1995-05-05       3.3

或者,可以使用提供更精细控制的轴规范来完成重塑(请参见下面的链接):

spec <- a %>%
    build_longer_spec(cols = -ID) %>%
    dplyr::transmute(.name = .name,
                     group = readr::parse_number(name),
                     .value = stringr::str_extract(name, "Start|End|Value"))

pivot_longer(a, spec = spec)

由reprex包(v0.2.1)于2019-03-26创建

另请参见:https://tidyr.tidyverse.org/articles/pivot.html

裴俊豪
2023-03-14

<代码>数据。表的融化函数可以融化到多个列中。利用这一点,我们可以简单地做到:

require(data.table)
melt(setDT(dat), id=1L,
     measure=patterns("Start$", "End$", "^Value"), 
     value.name=c("DateRangeStart", "DateRangeEnd", "Value"))

#    ID variable DateRangeStart DateRangeEnd Value
# 1:  1        1         1/1/90       3/1/90   4.4
# 2:  1        2         4/5/91       6/7/91   6.2
# 3:  1        3         5/5/95       6/6/96   3.3

或者,也可以通过列位置引用三组测量列:

melt(setDT(dat), id = 1L, 
     measure = list(c(2,5,8), c(3,6,9), c(4,7,10)), 
     value.name = c("DateRangeStart", "DateRangeEnd", "Value"))
薛俊美
2023-03-14
reshape(dat, idvar="ID", direction="long", 
             varying=list(Start=c(2,5,8), End=c(3,6,9), Value=c(4,7,10)),
             v.names = c("DateRangeStart", "DateRangeEnd", "Value") )
#-------------
    ID time DateRangeStart DateRangeEnd Value
1.1  1    1          1/1/90        3/1/90    4.4
1.2  1    2          4/5/91        6/7/91    6.2
1.3  1    3          5/5/95        6/6/96    3.3

(根据Josh的建议添加了v.names。)

 类似资料:
  • 我需要将长数据格式(long)转换为宽格式(wide),条件如下(如果可能): 1) 所有数据文件都将是具有相同结构(id、名称、值)的长格式(long),但每个数据文件将具有不同的变量、值和变量数: 2) 每个数据文件将是不同的变量混合物(因子、整数、数字)。有些因素可能每个案例都有多个级别(从长远来看是水果和肉),我想为这些因素中的每个级别创建一个单独的虚拟变量(逻辑)。因子和数值变量的数量将

  • 问题内容: 我有一些格式的数据: 我需要将其转换为格式 如何在SQL中执行此操作? 问题答案: 如果您的得分列是固定的,并且不需要汇总,则可以使用多个和语句来生成所需的数据形状。例如 SQL小提琴:http://sqlfiddle.com/#!6 / f54b2 / 4/0

  • 我有一个非常简单的,其中每个单元格都包含一个列表。我想将列表中的每个元素拆分为它自己的列。我可以通过导出值,然后创建一个新的

  • 我的数据集的形式为: 我想把它转换成: 如何使用pandas在Python中实现它? 它解决了感谢和感谢您的时间来帮助!!!1对所有

  • setColumn 样式影响范围为整列。 设置 range 参数为 A1:D1,第一反应是设置第一行的前四个单元格样式,但是实际效果确是设置 第一列、第二列、第三列、第四列 整列。 函数原型 setColumn(string $range, double $width [, resource $formatHandler]); string $range $config = ['path' =>

  • 问题内容: 我在mysql表中的数据具有长/高格式(如下所述),并希望将其转换为宽格式。我可以只使用sql吗? 用一个例子最容易解释。假设您具有有关M个国家/地区,N个键(例如,键可以是收入,政治领导人,地区,大洲等)的(国家/地区,键,值)信息。 SQL中是否可以使用宽格式的数据来创建新表? //这将为我获取所有键。 1)然后如何使用这些关键元素创建表? 2)然后如何填写表格值? 我很确定我可以