【问题标题】:Combining multiple columns in R?在R中组合多列?
【发布时间】:2021-05-28 22:24:41
【问题描述】:

有没有办法将一组列转移到 R 中自己的行中?

我目前有一个包含如下列标题的大型数据集:

Month Year Tenant 1 Name Tenant 1 Rate Tenant 1 Vacate Date Tenant 1 Notes Tenant 1 Name Tenant 2 Rate Tenant 2 Vacate Date Tenant 2 Notes
Jan 2001 Bob 1 2 3 Joe 1 2 3

我想合并这些信息,以便每个月和年中的每个租户都有自己的行。所以行应该是这样的:

Month Year Name Rate Date Notes
Jan 2001 Bob 1 2 3
Jan 2001 Joe 1 2 3

我认为这类似于 group_by() 但不知何故适用于多个列?

抱歉,格式笨拙!

【问题讨论】:

    标签: r


    【解决方案1】:

    首先,生成一个像你这样的例子(你的例子有两次“Tenant 1 Name”,但我猜这只是一个错字)。

    colnames<-c("Month","Year","Tenant 1 Name","Tenant 1 Rate","Tenant 1 Vacate Date","Tenant 1 Notes","Tenant 2 Name","Tenant 2 Rate","Tenant 2 Vacate Date","Tenant 2 Notes")
    fields<-c("Jan","2001","Bob","1","2","3","Joe","1","2","3")
    mat<-matrix(fields,nrow=1)
    colnames(mat)<-colnames
    View(mat)
    

    看起来像这样:

    现在,确定哪一列中有“名称”

    cols<-grep("Name",colnames(mat))
    cols
    

    然后,从这些列中提取名称:

    names<-mat[,cols]
    

    最后,填充一个新矩阵:

    newmat<-matrix(NA,nrow=0,ncol=6)
    for(n in names){
        whichcol<-which(mat[1,]==n)
        newline<-c(mat[,1:2],mat[,whichcol:(whichcol+3)])
        newmat<-rbind(newmat,newline)
    }
    View(newmat)
    

    它会产生你正在寻找的东西:

    但是,我感觉您正在使用的数据集具有更多层次的复杂性(例如,多行),需要更复杂的解决方案。如果是这种情况,请告诉我们!

    【讨论】:

      【解决方案2】:

      如果 'Joe' 的列名是 'Tenant 2 Name',请使用 pivot_longer,将 cols 指定为除 'Month'、'Year' 之外的所有内容,并使用 names_pattern,捕获列名子字符串作为字符串末尾 ($) 的非空格 (\\S+) 的字符

      library(tidyr)
      pivot_longer(df1, cols = -c(Month, Year), 
           names_to = ".value", names_pattern = ".*\\s+(\\S+)$")
      

      -输出

      # A tibble: 2 x 6
      #  Month  Year Name   Rate  Date Notes
      #  <chr> <int> <chr> <int> <int> <int>
      #1 Jan    2001 Bob       1     2     3
      #2 Jan    2001 Joe       1     2     3
      

      数据

      df1 <- structure(list(Month = "Jan", Year = 2001L, `Tenant 1 Name` = "Bob", 
          `Tenant 1 Rate` = 1L, `Tenant 1 Vacate Date` = 2L, `Tenant 1 Notes` = 3L, 
          `Tenant 2 Name` = "Joe", `Tenant 2 Rate` = 1L, `Tenant 2 Vacate Date` = 2L, 
          `Tenant 2 Notes` = 3L), class = "data.frame", row.names = c(NA, 
      -1L))
      

      【讨论】:

      • @AnoushiravanR 我想知道你为什么要捕获 3 个组,但是指定 NA 的选项很高兴知道,因为我不知道它会删除这些组
      • 关于使用的正则表达式,您正在捕获 3 个单词。它可以在数据中的任何位置。最后一个可以在末尾添加$ 以确保它始终选择最后一个单词
      • 是的,我在pivot_longer 的文档中找到了它,然后它提供了有关.value 的信息,它说我们可以使用NA 删除捕获组。如果我没记错删除分隔列的一部分,我们可以在separate 函数中使用这个技巧。
      • 你的意思可能是extract
      • 有时,我们可能认为某个特定的选项可能是多余的,但它仍然提供了一些很棒的信息。谢谢
      【解决方案3】:

      感谢亲爱的@akrun 一如既往的微妙提示。我在最后一个捕获组中添加了$,以确保它始终选择最后一个。 这可能听起来有点冗长,但它也可以解决问题。我创建了 3 个名称模式,将前两个转换为 NA 并捕获第三个:

      library(dplyr)
      library(tidyr)
      
      df1 %>% 
        pivot_longer(!c(Month, Year), names_to = c(NA, NA, ".value"),
                     names_pattern = "(\\w+) (\\w+) (\\w+$)")
      
      # A tibble: 2 x 6
        Month  Year Name   Rate Vacate Notes
        <chr> <int> <chr> <int>  <int> <int>
      1 Jan    2001 Bob       1      2     3
      2 Jan    2001 Joe       1      2     3
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-12-20
        • 2021-04-09
        • 1970-01-01
        • 2016-05-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多