【问题标题】:Turn 2 short columns into 1 longer col将 2 个短列变成 1 个较长的列
【发布时间】:2021-02-19 05:42:45
【问题描述】:

请帮忙,谢谢。 10k 行的解决方案应该是自动的(20k 个国家,每组 10k)

原表

|Group1|Group2|Population1|Pop2|
|--|--|--|--|
|"USA"|  "ENG"|  1000|   502|
|"RUS"|  "FRC"|  1200|   200|
|"UEC"|  "IND"|  120|   100|
| "EST"|  "CAU"|  100|   500|
|"VNE"|  "CAM"|  200|   800|
*with other 10000 rows*

预期的表格

|Nation|Population|
|--|--|
|"USA"|1000|
|"RUS"|1200|
|  "ENG"|502|
|  "FRC"|200|
|"ENG"|502|
|"FRC"|200|
|"IND"|100|
|"CAU"|500|
|"CAM"|800|


【问题讨论】:

    标签: r join bind tibble


    【解决方案1】:

    使用tidyr

    library(tidyr)
    
    dat <- data.frame(G1 = c("USA", "UK"), G2 = c("FRA", "CAN"), Pop1 = c(123, 234), Pop2 = c(345, 432))
    
    pivot_longer(dat, everything(), names_to = c(".value", NA), names_pattern = "(.*)(1|2)$")
    
    # A tibble: 4 x 2
      G       Pop
      <chr> <dbl>
    1 USA     123
    2 FRA     345
    3 UK      234
    4 CAN     432
    

    编辑: 使用更大的数据框运行它:

    dat_big <- uncount(dat, weights = 100000) # Now with 200,000 rows
    
    bench::mark(time = {
      pivot_longer(dat_big, everything(), names_to = c(".value", NA), names_pattern = "(.*)(1|2)$")
    })
    
    expression     min  median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time   
      <bch:expr> <bch:t> <bch:t>     <dbl> <bch:byt>    <dbl> <int> <dbl>   <bch:tm>
    1 time        37.5ms  37.5ms      26.6    39.7MB     320.     1    12     37.5ms 
    

    【讨论】:

    • 反正做得更快,实际表是10k行
    • 查看我的编辑:200,000 行需要 37.5 毫秒。
    • 我的意思是这段代码"dat
    • 我在这里创建的 dat_big 对象有 200,000 行,即实际数据的 20 倍。您告诉我的内容似乎与我提供的内容不一致。
    • 我只是编辑原始数据,请看看,我们有没有其他不创建dat步骤的方法
    【解决方案2】:

    更新使用来自 baseR 的 rbind,(假设您的数据名称是 dat 否则用以下语法替换它)

    #enter column names of final data in a vector
    Names <- c("Country", "Population")
    
    #for final output
    rbind(setNames(dat[,c(1,3)], Names), setNames(dat[,c(2,4)], Names))
    

    创建示例数据的演示

    
    dat <- data.frame(G1 = c("USA", "UK"), G2 = c("FRA", "CAN"), Pop1 = c(123, 234), Pop2 = c(345, 432))
    dat
       G1  G2 Pop1 Pop2
    1 USA FRA  123  345
    2  UK CAN  234  432
    
    > rbind(setNames(dat[,c(1,3)], Names), setNames(dat[,c(2,4)], Names))
      Country Population
    1     USA        123
    2      UK        234
    3     FRA        345
    4     CAN        432
    
    

    【讨论】:

    • 反正做得更快,实际表是10k行
    【解决方案3】:
    x<-c(df2$Group1, df2$Group2)
    
    y<-c(df2$Population1,df2$Pop2)
    
    z<-bind_cols(x,y)
    
    z %>% as.data.frame() %>% rename(nation=...1, Pop=...2)
    

    【讨论】:

    • 社区鼓励在代码中添加解释,而不是纯粹基于代码的答案(参见here)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-13
    • 1970-01-01
    相关资源
    最近更新 更多