【问题标题】:Reshaping a table in R while parsing information from column names and using it to collect information from specific columns在从列名解析信息并使用它从特定列中收集信息的同时重塑 R 中的表
【发布时间】:2020-12-21 02:21:42
【问题描述】:

我有这个组织得很糟糕的数据表,其中有数百列(子集在下面给出)

列的名称以点分隔,其中第一个字段包含有关对象类型(例如 Item123、object_AB 等)的信息,没有任何命名约定。这些列也没有特定的顺序。 其他列共享对象字段的类型,并且还具有该对象的某些属性的名称(例如颜色、制造商等)。

Item123.type.value  Item123.mass.value  Item123.color.value object_AB.type.value  object_AB.mass.value  object_AB.color.value
Desk  11.2  blue  Chair 2.3 orange
Desk 14.2 red Sofa  22  grey
Armchair  23.3  black  Monitor 2.2 white

已编辑:添加 dput() 结构:

structure(list(Item123.type.value = structure(c(2L, 2L, 1L),
levels = c("Armchair", "Desk"), class = "factor"), Item123.mass.value = structure(1:3,
levels = c("11.2", "14.2", "23.3"), class = "factor"), Item123.color.value = structure(c(2L,
3L, 1L), levels = c("black", "blue", "red"), class = "factor"),
object_AB.type.value = structure(c(1L, 3L, 2L), levels = c("Chair",
"Monitor", "Sofa"), class = "factor"), object_AB.mass.value = structure(c(2L,
3L, 1L), levels = c("2.2", "2.3", "22"), class = "factor"),
object_AB.color.value = structure(c(2L, 1L, 3L), levels = c("grey",
"orange", "white"), class = "factor")), row.names = c(NA_integer_,
-3L), class = "data.frame")

我需要将表格转换成这样(行的顺序无关紧要):

type  name  mass  color
Item123  Desk  11.2  blue
Item123  Desk  14.2  red
object_AB  Chair 2.3 orange
object_AB  Sofa  22  grey
Item123  Armchair  23.3  black
object_AB  Monitor 2.2 white

如果能得到任何帮助,我将不胜感激!

【问题讨论】:

  • 示例数据现在位于原始帖子中。很抱歉!

标签: r data.table reshape


【解决方案1】:

您可以在此处使用pivot_longer 指定names_pattern 从列名中获取数据。

tidyr::pivot_longer(df, 
                    cols = everything(), 
                    names_to = c('name', '.value'),
                    names_pattern = '(\\w+)\\.(\\w+)\\.')

# A tibble: 6 x 4
#  name      type     mass  color 
#  <chr>     <fct>    <fct> <fct> 
#1 Item123   Desk     11.2  blue  
#2 object_AB Chair    2.3   orange
#3 Item123   Desk     14.2  red   
#4 object_AB Sofa     22    grey  
#5 Item123   Armchair 23.3  black 
#6 object_AB Monitor  2.2   white 

【讨论】:

  • 两种解决方案都很好用。 @Duck 的第一个对于学习连接非常有用,但是这个更优雅。谢谢你们俩!
【解决方案2】:

我会建议这种方法,使用您添加的数据作为 df 可能会是最长和无聊的。代码在您的列名中查找特定模式,对其进行整形并最终合并所有:

library(tidyverse)
#Code
df %>% select(contains('type')) %>%
  mutate(id=1:n()) %>%
  pivot_longer(-id) %>%
  separate(name,into = c(paste0('V',1:3)),sep = '\\.') %>%
  select(-c(V2,V3)) %>%
  rename(Value1=value) %>%
  left_join(df %>% select(contains('mass')) %>%
              mutate(id=1:n()) %>%
              pivot_longer(-id) %>%
              separate(name,into = c(paste0('V',1:3)),sep = '\\.') %>%
              select(-c(V2,V3)) %>%
              rename(Value2=value)) %>%
  left_join(df %>% select(contains('color')) %>%
              mutate(id=1:n()) %>%
              pivot_longer(-id) %>%
              separate(name,into = c(paste0('V',1:3)),sep = '\\.') %>%
              select(-c(V2,V3)) %>%
              rename(Value3=value))

输出:

# A tibble: 6 x 5
     id V1        Value1   Value2 Value3
  <int> <chr>     <chr>     <dbl> <chr> 
1     1 Item123   Desk       11.2 blue  
2     1 object_AB Chair       2.3 orange
3     2 Item123   Desk       14.2 red   
4     2 object_AB Sofa       22   grey  
5     3 Item123   Armchair   23.3 black 
6     3 object_AB Monitor     2.2 white 

【讨论】:

  • 效果很好!是否可以将脚本推广到包含未知数量的包含属性(例如名称、颜色、质量、密度等)的列?
  • @AdiLavy 非常感谢你。当然,您可以添加额外的管道,如果您有很多模式,您可以尝试使用循环,这将是适合代码的选项:)
猜你喜欢
  • 2023-02-21
  • 1970-01-01
  • 2020-02-10
  • 2017-10-05
  • 1970-01-01
  • 1970-01-01
  • 2018-01-22
  • 1970-01-01
  • 2017-06-10
相关资源
最近更新 更多