【问题标题】:Split column into intervals based on row content根据行内容将列拆分为间隔
【发布时间】:2018-11-08 19:15:37
【问题描述】:

我正在尝试将单列数据框转换为单独的列 - 数据中的主要描述符是“项目编号”,然后包括价格、日期、颜色等信息。我只想拆分列取决于行号,但由于每个项目的信息量不同,这实际上并不奏效。

我一直在玩这个,但没有发现任何可以接近的东西,因为我不能使用正则表达式来创建一个单独的列(例如使用 str_which),因为信息差异很大项目到项目。如何使用正则表达式创建间隔,然后我可以将列拆分为(因此我需要在单独列中包含“项目”的每一行之间的信息)。示例数据如下。

data

item 1
$600
red
item 2
$70
item 3
$430
orange
10/11/2017

谢谢!

【问题讨论】:

  • 制作一个数据框列表(每个都是一个项目及其关联数据),然后将它们附加在一起并将NA分配给空列。
  • @Masoud 这就是我想弄清楚的方法。我正在尝试按项目拆分此数据(我收到这样的数据),但由于每个项目具有不同数量的关联行,具有不同的内容,我不确定如何

标签: r


【解决方案1】:

这是一个根据您希望最终数据集的外观重新格式化数据的功能。对于该函数,您提供数据框DF、变量var,以及按正确顺序colnamesbyitem 的列名向量来选择输出格式(默认为TRUE,它输出一个每个item 一行的数据框:

library(tidyverse)

df_transform = function(DF, var, colnames, byitem = TRUE){
  if(byitem){
    ID = sym("rowid")
  }else{
    ID = sym("id")
  }
  DF %>%
    group_by(id = paste0("item", cumsum(grepl("item", var)))) %>%
    mutate(rowid = replace(2:n(), 2:n(), setNames(colnames[1:(n()-1)], 2:n()))) %>%
    filter(!grepl("item", var)) %>%
    spread(!!ID, var)
}

输出:

> df_transform(df, var, c("price", "color", "date"))

# A tibble: 3 x 4
# Groups:   id [3]
  id    color  date       price
  <chr> <fct>  <fct>      <fct>
1 item1 red    <NA>       $600 
2 item2 <NA>   <NA>       $70  
3 item3 orange 10/11/2017 $430 


> df_transform(df, var, c("price", "color", "date"), byitem = FALSE)

# A tibble: 3 x 4
  rowid item1 item2 item3     
  <chr> <fct> <fct> <fct>     
1 color red   <NA>  orange    
2 date  <NA>  <NA>  10/11/2017
3 price $600  $70   $430  

请注意,如果中间有缺失值,这将不起作用,因为列名是按位置分配的。

数据:

df <- structure(list(var = structure(c(5L, 2L, 9L, 6L, 3L, 7L, 1L, 
8L, 4L), .Label = c("$430", "$600", "$70", "10/11/2017", "item_1", 
"item_2", "item_3", "orange", "red"), class = "factor")), .Names = "var", class = "data.frame", row.names = c(NA, 
-9L))

【讨论】:

  • 非常感谢!这很棒。不过,我想知道(很抱歉在我最初的问题中没有说清楚,并且忘记提供可重现的数据),如果“价格”和“颜色”列并不总是可以做些什么以相同的顺序(如,并不总是在第 2 行)。再次感谢您!
  • @I.I.好吧,除了你的价值观的位置,没有办法知道文字“100 美元”应该是价格还是其他东西。除非有另一列来表示每一行的列名,或者天真地假设带有美元符号的值总是“价格”,否则恐怕你的数据太模糊,无法进行这种转换。
  • @I.I.如果你愿意假设“$”总是price,字符总是color,日期总是date,那么我可以修改我的答案以适应这种情况。
  • 谢谢!这是有道理的......我想我会继续尝试这段代码,但尝试一些不同的正则表达式来取出列......不过,我还有一个问题 - 有很多重复的一组无用信息中的行(例如,表 1 将有两行橙色,仅作为示例),删除重复行会删除所有橙色实例(我不想要)。我想知道是否有办法在不匹配时使用 mutate + case_when 删除行。我希望这是有道理的 - 再次感谢您!
  • @I.I.您的意思是只保留每个重复行的第一行吗?也许您应该更新您的问题并提供预期的输出来说明您的意思。
猜你喜欢
  • 2014-06-07
  • 2021-08-07
  • 2016-06-04
  • 2017-11-04
  • 1970-01-01
  • 1970-01-01
  • 2018-04-20
  • 2016-12-01
  • 2017-12-08
相关资源
最近更新 更多