使用 Tidyverse 将数据从一列转换为多列

Transform data from a column into multiple columns with Tidyverse

所以我抓取了一个网站,数据是这样的:

# A tibble: 150 x 1
   data                                                                              
   <chr>                                                                             
 1 HELSFYR / HOVINENGA - Leilighet fra 2019 med balkong, garasjeplass og el-billading
 2 Innspurten 10B, Oslo                                                              
 3 56 m²17 500 kr                                                                    
 4 Fin 3-roms leilighet til leie på Grunerløkka                                      
 5 SANNERGATA 13 A, Oslo                                                             
 6 55 m²14 200 kr                                                                    
 7 Torshov Torg - Meget pen 3-roms med balkong Sandakerveien 22 B, 0473 Oslo         
 8 SANDAKERVEIEN 22 B, Oslo                                                          
 9 51 m²16 500 kr                                                                    
10 FROGNER/VIKA- 3-roms leilighet med god standard. Ledig 1 juli!                    
# ... with 140 more rows

它实际上包含我需要的三列。如何将一列转换为多列,每 1-3 行分成几列? 所需的输出将是:

# A tibble: 3 x 3
  title                                          adress                   info          
  <chr>                                          <chr>                    <chr>         
1 "HELSFYR / HOVINENGA - Leilighet fra 2019 "    Innspurten 10B, Oslo     56 m²17 500 kr
2 "Fin 3-roms leilighet til leie på Grunerløkka" SANNERGATA 13 A, Oslo    55 m²14 200 kr
3 "Torshov Torg - Meget pen 3-roms med balko"    SANDAKERVEIEN 22 B, Oslo 51 m²16 500 kr

我的数据

Dput()

structure(list(data = c("HELSFYR / HOVINENGA - Leilighet fra 2019 med balkong, garasjeplass og el-billading", 
"Innspurten 10B, Oslo", "56 m²17 500 kr", "Fin 3-roms leilighet til leie på Grunerløkka", 
"SANNERGATA 13 A, Oslo", "55 m²14 200 kr", "Torshov Torg - Meget pen 3-roms med balkong Sandakerveien 22 B, 0473 Oslo", 
"SANDAKERVEIEN 22 B, Oslo", "51 m²16 500 kr")), row.names = c(NA, 
-9L), class = c("tbl_df", "tbl", "data.frame"))

你可以这样做:

df$data %>% 
  matrix(nrow = 3) %>% 
  t() %>% 
  as.data.frame() %>% 
  setNames(c("Title", "Address", "Info")) %>% 
  as_tibble()
#> # A tibble: 3 x 3
#>   Title                                                            Address Info 
#>   <chr>                                                            <chr>   <chr>
#> 1 HELSFYR / HOVINENGA - Leilighet fra 2019 med balkong, garasjepl~ Innspu~ 56 m~
#> 2 Fin 3-roms leilighet til leie på Grunerløkka                     SANNER~ 55 m~
#> 3 Torshov Torg - Meget pen 3-roms med balkong Sandakerveien 22 B,~ SANDAK~ 51 m~

reprex package (v2.0.1)

于 2022-05-04 创建

虽然我最喜欢@Allan Cameron 的解决方案。这是 tidyverse 方法: 这将另外删除 title 列中逗号之后的所有内容:

library(dplyr)
library(tidyr)
library(stringr)

df %>% 
  group_by(group = as.integer(gl(n(), 3, n()))) %>% 
  summarise(helper = paste(data, collapse = "|")) %>% 
  separate(helper, c("title", "adress", "info"), sep = "\|", remove = TRUE) %>% 
  ungroup() %>% 
  select(-group) %>% 
  mutate(title = str_remove_all(title, '\,.*'))
  
   title                                                          adress                   info          
  <chr>                                                          <chr>                    <chr>         
1 HELSFYR / HOVINENGA - Leilighet fra 2019 med balkong           Innspurten 10B, Oslo     56 m²17 500 kr
2 Fin 3-roms leilighet til leie på Grunerløkka                   SANNERGATA 13 A, Oslo    55 m²14 200 kr
3 Torshov Torg - Meget pen 3-roms med balkong Sandakerveien 22 B SANDAKERVEIEN 22 B, Oslo 51 m²16 500 kr

你可以这样做:

setNames(
  bind_cols(lapply(1:3, function(i) data[seq(i,nrow(data),3),])),
  c("title","address","info")
)

输出:

  title                                                                              address                  info          
  <chr>                                                                              <chr>                    <chr>         
1 HELSFYR / HOVINENGA - Leilighet fra 2019 med balkong, garasjeplass og el-billading Innspurten 10B, Oslo     56 m²17 500 kr
2 Fin 3-roms leilighet til leie på Grunerløkka                                       SANNERGATA 13 A, Oslo    55 m²14 200 kr
3 Torshov Torg - Meget pen 3-roms med balkong Sandakerveien 22 B, 0473 Oslo          SANDAKERVEIEN 22 B, Oslo 51 m²16 500 kr

您可以使用 scan() 函数并使用 what 参数来定义字段:

tibble::as_tibble(scan(text = df$data, what = list(title = "", address = "", info = ""), sep = "\n"))

Read 3 records
# A tibble: 3 × 3
  title                                                                              address                  info          
  <chr>                                                                              <chr>                    <chr>         
1 HELSFYR / HOVINENGA - Leilighet fra 2019 med balkong, garasjeplass og el-billading Innspurten 10B, Oslo     56 m²17 500 kr
2 Fin 3-roms leilighet til leie på Grunerløkka                                       SANNERGATA 13 A, Oslo    55 m²14 200 kr
3 Torshov Torg - Meget pen 3-roms med balkong Sandakerveien 22 B, 0473 Oslo          SANDAKERVEIEN 22 B, Oslo 51 m²16 500 kr

有可能你在抓取数据的同时也可以在上游解决这个问题。