【问题标题】:Creating multiple new long columns at once from wide data in R?从R中的宽数据一次创建多个新的长列?
【发布时间】:2020-08-28 23:02:44
【问题描述】:

我经常进行这种数据清理,我试图将 Qualtrics 调查中以宽格式收集的数据转换为长格式。我通常有例如我针对每个国家/地区多次提出的两个主要问题、一些协变量和一个 ID 变量。下面的代码以这种格式创建示例数据。我想将数据从下面的宽格式转换为长格式,其中一列是国家,两列是主要问题,一列是协变量,一列是 ID 变量。我一直在这样做,但我绝对确定这是一种糟糕、低效的方式,但我找不到如何更有效地完成这项确切任务的示例。如果有人可以向我展示一种更有效的方法,我将不胜感激,最好使用 base R 或 tidyverse。

require(tidyr)
#make example data
dfLength = 500

wide = data.frame(happy_Belgium = runif(dfLength), happy_US= runif(dfLength), happy_UK= runif(dfLength), angry_Belgium= runif(dfLength), angry_US= runif(dfLength), angry_UK= runif(dfLength), id = 1:dfLength, other_variable = runif(dfLength))


#Make an individual long dataframe for each measure
longHappy = wide %>%
  gather(key="country", value="happy", happy_Belgium:happy_UK)
longAngry = wide %>%
  gather(key="country", value="angry", angry_Belgium:angry_UK)
#Make a variable for the country based on the format of the question titles
longHappy$country = substring(longHappy$country, 7, nchar(longHappy$country))
longAngry$country = substring(longAngry$country, 7, nchar(longAngry$country))
#Merge the two long variables
long = merge(longHappy, longAngry)
#Get rid of columns I don't need
keeps = c("id", "other_variable", "happy", "angry", "country")
long = long[,names(long) %in% keeps]

【问题讨论】:

    标签: r tidyverse data-cleaning


    【解决方案1】:

    试试:

    library(tidyr)
    
    long <- 
      wide %>% 
      pivot_longer(cols = contains("y_"), names_to = c(".value", "country"), names_sep = "_")
    
    head(long)
    #> # A tibble: 6 x 5
    #>      id other_variable country happy  angry
    #>   <int>          <dbl> <chr>   <dbl>  <dbl>
    #> 1     1          0.822 Belgium 0.610 0.0304
    #> 2     1          0.822 US      0.681 0.352 
    #> 3     1          0.822 UK      0.727 0.708 
    #> 4     2          0.693 Belgium 0.170 0.526 
    #> 5     2          0.693 US      0.462 0.836 
    #> 6     2          0.693 UK      0.466 0.577
    

    数据

    dfLength = 500
    
    wide = data.frame(happy_Belgium = runif(dfLength), 
                      happy_US= runif(dfLength),
                      happy_UK= runif(dfLength), 
                      angry_Belgium= runif(dfLength), 
                      angry_US= runif(dfLength), 
                      angry_UK= runif(dfLength), 
                      id = 1:dfLength, 
                      other_variable = runif(dfLength))
    
    

    reprex package (v0.3.0) 于 2020-05-12 创建

    【讨论】:

    • 这个和另一个答案都完成了这个问题!检查另一个,因为它可能更灵活一点,但是这个和另一个都很棒,谢谢
    • 毫无疑问,akrun 的选项更加稳健和通用:尽管原理相同,但这个选项正好适合您的数据!
    【解决方案2】:

    带有matches 的选项用于选择以“快乐”或“愤怒”开头的列名

    library(dplyr)
    library(tidyr)
    wide %>% 
     pivot_longer(cols = matches('^(happy|angry)'), 
           names_to = c(".value", "country"), names_sep = "_")
    # A tibble: 1,500 x 5
    #      id other_variable country  happy angry
    #   <int>          <dbl> <chr>    <dbl> <dbl>
    # 1     1          0.113 Belgium 0.430  0.295
    # 2     1          0.113 US      0.359  0.410
    # 3     1          0.113 UK      0.824  0.176
    # 4     2          0.379 Belgium 0.979  0.446
    # 5     2          0.379 US      0.624  0.911
    # 6     2          0.379 UK      0.0781 0.741
    # 7     3          0.785 Belgium 0.0606 0.590
    # 8     3          0.785 US      0.461  0.149
    # 9     3          0.785 UK      0.913  0.404
    #10     4          0.486 Belgium 0.204  0.516
    # … with 1,490 more rows
    

    或者用-删除cols中不需要的列

    wide %>% 
      pivot_longer(cols = -c(id, other_variable), 
              names_to = c(".value", "country"), names_sep = "_")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-16
      • 2023-02-23
      • 2017-11-02
      相关资源
      最近更新 更多