【问题标题】:Pivot_longer: Rotating multiple columns of data with same data typesPivot_longer:旋转具有相同数据类型的多列数据
【发布时间】:2021-05-28 10:18:09
【问题描述】:

我正在尝试将多列数据旋转为单个数据类型一致的列。

我在下面创建了一个最小示例。

library(tibble)
library(dplyr)


# I have data like this
df <- tibble(contact_1_prefix=c('Mr.','Mrs.','Dr.'),
             contact_2_prefix=c('Dr.','Mr.','Mrs.'),
             contact_1 = c('Bob Johnson','Robert Johnson','Bobby Johnson'),
             contact_2 = c('Tommy Two Tones','Tommy Three Tones','Tommy No Tones'),
             contact_1_loc = c('Earth','New York','Los Angeles'),
             contact_2_loc = c('London','Geneva','Paris'))

# My attempt at a solution:  
df %>%  rename(contact_1_name=contact_1, 
               contact_2_name=contact_2) %>% 
        pivot_longer(cols=c(matches('_[12]_')), 
               names_to=c('.value','dat'),
               names_pattern = "(.*)_[1-2]_(.*)") %>% 
        pivot_wider(names_from='dat',values_from='contact')

#What I want is to widen that data to achieve a tibble with these two example lines
df_desired <- tibble(name=c('Bob Johnson','Tommy Two Tones'),
                     loc =c('Earth','London'),
                     prefix=c('Mr.','Dr.'))

我想要 name 下的所有名称、loc 下的所有位置以及 prefix 下的所有前缀。

如果我只使用中间语句中的这个 sn-p:

df %>%  rename(contact_1_name=contact_1, 
               contact_2_name=contact_2) %>% 
        pivot_longer(cols=c(matches('_[12]_')), 
               names_to=c('.value','dat'),
               names_pattern = "(.*)_[1-2]_(.*)") 

输出的dput是:

structure(list(dat = c("prefix", "prefix", "name", "name", "loc", 
"loc", "prefix", "prefix", "name", "name", "loc", "loc", "prefix", 
"prefix", "name", "name", "loc", "loc"), contact = c("Mr.", "Dr.", 
"Bob Johnson", "Tommy Two Tones", "Earth", "London", "Mrs.", 
"Mr.", "Robert Johnson", "Tommy Three Tones", "New York", "Geneva", 
"Dr.", "Mrs.", "Bobby Johnson", "Tommy No Tones", "Los Angeles", 
"Paris")), row.names = c(NA, -18L), class = c("tbl_df", "tbl", 
"data.frame"))

据此,我认为 pivot_wider 肯定是解决方案,但存在名称冲突。

我假设单个 pivot_longer 语句将完成任务。我仔细研究了Gathering wide columns into multiple long columns using pivot_longer,但不太明白这一点。我不得不承认我不太明白 names_to = c(".value", "group") 短语的作用。

无论如何,感谢您的帮助。

谢谢

【问题讨论】:

    标签: r tidyr


    【解决方案1】:

    你走在正确的道路上。需要重命名,因为只有名称列没有任何后缀来识别它们。 .value 标识要唯一标识为新列的原始列名的一部分。如果在最后一个下划线之前删除所有内容,则剩下的部分是新列名,您可以在 names_pattern 中使用正则表达式指定。

    library(dplyr)
    library(tidyr)
    
    df %>%  
      rename(contact_1_name=contact_1, 
             contact_2_name=contact_2) %>%
      pivot_longer(cols = everything(), 
                   names_to = '.value', 
                   names_pattern = '.*_(\\w+)')
    
    #  prefix name              loc        
    #  <chr>  <chr>             <chr>      
    #1 Mr.    Bob Johnson       Earth      
    #2 Dr.    Tommy Two Tones   London     
    #3 Mrs.   Robert Johnson    New York   
    #4 Mr.    Tommy Three Tones Geneva     
    #5 Dr.    Bobby Johnson     Los Angeles
    #6 Mrs.   Tommy No Tones    Paris      
    

    【讨论】:

      【解决方案2】:

      这是使用split.default的解决方案

      data.table::rbindlist( 
        lapply( split.default( df, gsub( "[^0-9]+", "", names(df) ) ),
                data.table::setnames, 
                new = c("prefix", "name", " loc" ) ) )
      #   prefix              name         loc
      # 1:    Mr.       Bob Johnson       Earth
      # 2:   Mrs.    Robert Johnson    New York
      # 3:    Dr.     Bobby Johnson Los Angeles
      # 4:    Dr.   Tommy Two Tones      London
      # 5:    Mr. Tommy Three Tones      Geneva
      # 6:   Mrs.    Tommy No Tones       Paris
          
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-26
        • 2014-05-22
        • 1970-01-01
        • 1970-01-01
        • 2019-07-24
        • 2016-09-10
        • 2017-02-08
        相关资源
        最近更新 更多