使用tidytext::unnest_tokens与聚合相反的操作。多个变量和大写字母

3

这个问题的基础上,我想要执行与aggregate相反的任务(或者像下面MWE中的data.table等效函数),以便从df2开始再次获得df1

因此,任务是从df2重新生成df1。为此,我尝试了tidytext::unnest_tokens,但是当需要“解聚”多个变量(modelscountriesyears)时,我无法弄清楚如何使其正常工作。

保留原始变量的大写形式也是不错的。

tidytext::unnest_tokens之外的任何优雅的解决方案都将被接受!谢谢!

这是MWE:

####MWE
library(data.table)
library(tidytext)
df1 <- data.frame(brand=c(rep('A',4), rep('B',5), rep('C',3), rep('D',2),'E'),
                  model=c('A1','A1','A2','A3','B1','B2','B2','B2','B3','C1','C1','C2','D1','D2','E1'),
                  country=c('P','G','S','S','P','P','F','I','D','S','F','F','G','I','S'),
                  year=c(91,92,93,94,98,95,87,99,00,86,92,92,93,95,99))
df1
dd <- data.table(df1)
df2 <- as.data.frame(dd[, list(models=paste(model, collapse=' /// '),
                               countries=paste(country, collapse=' /// '),
                               years=paste(year, collapse=' /// ')),
                        by=list(brand=brand)])
df2
df1b <- df2 %>% 
  unnest_tokens(model, models, token = "regex", pattern = " /// ")
df1b
####
2个回答

2
我会使用 dplyr::mutate_at()stringr::str_split()tidyr::unnest() 来完成这个任务。
library(tidyverse)  

df2 %>%
  mutate_at(vars(models:years), ~ str_split(., pattern = " /// ")) %>%
  unnest()

#> # A tibble: 15 x 4
#>    brand models countries years
#>    <chr> <chr>  <chr>     <chr>
#>  1 A     A1     P         91   
#>  2 A     A1     G         92   
#>  3 A     A2     S         93   
#>  4 A     A3     S         94   
#>  5 B     B1     P         98   
#>  6 B     B2     P         95   
#>  7 B     B2     F         87   
#>  8 B     B2     I         99   
#>  9 B     B3     D         0    
#> 10 C     C1     S         86   
#> 11 C     C1     F         92   
#> 12 C     C2     F         92   
#> 13 D     D1     G         93   
#> 14 D     D2     I         95   
#> 15 E     E1     S         99

请注意,这里的最后一列仍然是chr类型,因此如果您想将其转换回数字类型,则需要再使用一个mutate()函数。


1
我们可以使用 separate_rows
library(tidyverse)
res <- df2 %>% 
         separate_rows(models, countries, years, convert = TRUE) %>%
         rename_all(funs(paste0(names(df1)))) %>% #just to make the column names same as df1
         mutate(year = as.numeric(year)) #convert to numeric to match df1 column type
all.equal(res, df1 %>% 
                  mutate_at(2:3, as.character), check.attributes = FALSE )
#[1] TRUE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接