【问题标题】:Merging two types of columns in parallel using dplyr and tidyr使用 dplyr 和 tidyr 并行合并两种类型的列
【发布时间】:2014-06-20 07:06:09
【问题描述】:

我正在尝试将一些代码从plyr 移植到dplyr

在特定情况下,我想将 2 种列组合在一起:nameXpropX(请参阅下面的示例数据框 foo),以及一个 id 列。我使用 ddply 得到的结果给了我一个只有 3 列的数据框,idnameprop(请参阅下面的数据框 bar)。

library(plyr)

foo <- rbind(
  data.frame(
    id = 'A',
    name1 = "dXz",
    prop1 = 20,
    name2 = "Rpt",
    prop2 = 65,
    name3 = "YYq",
    prop3 = 15
  ),
  data.frame(
    id = 'B',
    name1 = "hut",
    prop1 = 30,
    name2 = "TPn",
    prop2 = 50,
    name3 = "pTm",
    prop3 = 20
  ),
  data.frame(
    id = 'C',
    name1 = "JpT",
    prop1 = 45,
    name2 = "Fil",
    prop2 = 25,
    name3 = "jjS",
    prop3 = 30
  )
)

bar <- ddply(
  foo, 
  .(id), 
  function(x) {
    data.frame(
      id = as.character(x$id), 
      name = c(as.character(x$name1), as.character(x$name2),as.character(x$name3),as.character(x$name4),as.character(x$name5)), 
      prop = c(x$prop1,x$prop2,x$prop3,x$prop4,x$prop5)
    )
  }
)

我一直在尝试使用dplyrtidyr 给出的最新运算符,但我似乎无法进行两个并行分组操作。

foo %>% 
  gather(name, prop, -id)

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    你在正确的轨道上。关键是这里需要考虑两件事:首先,您需要定义哪些“name”和“prop”列应该放在一起。其次,您必须将所有不同的列名转换为只有两个不同的名称。

    grps <- c("name1" = "g1",
             "prop1" = "g1",
             "name2" = "g2",
             "prop2" = "g2",
             "name1.1" = "g3",
             "prop2.1" = "g3")
    
    
    foo %>% 
      tbl_df %>%
      gather(varname,value,-id) %>%
      mutate(grpname = grps[varname]) %>%
      mutate(varname2 = varname %>% grepl("^name",.) %>% ifelse("name",varname),
             varname3 = varname %>% grepl("^prop",.) %>% ifelse("prop",varname2)) %>%
      select(id,grpname,varname3,value) %>%
      spread(varname3,value)
    
      id grpname name prop
    1  A      g1  dXz   20
    2  A      g2  Rpt   65
    3  A      g3  YYq   15
    4  B      g1  hut   30
    5  B      g2  TPn   50
    6  B      g3  pTm   20
    7  C      g1  JpT   45
    8  C      g2  Fil   25
    9  C      g3  jjS   30
    

    【讨论】:

    • 单独使用会简单一点:foo %&gt;% gather(varname,value,-id) %&gt;% separate(varname, c("var", "num"), 4) %&gt;% spread(var, value, convert = TRUE)
    • 不错!如果变量名不同(例如name1proportion1),我们可以使用separate(varname, c("var", "num"), -1),对吗?
    • @hadley :以@AndrewMacDonald 的评论为基础,处理变量名称完全不同的情况的最优雅方法是什么——或者要拆分两个以上的名称(例如name1proportion1myclass1 等)?
    • @Pierre 后一种情况非常简单——您最终会得到更多级别的 var 列。如果你不能指望数字只是一个数字(例如name1name21),可能会更棘手。那么也许extract_numeric 会有所帮助
    猜你喜欢
    • 1970-01-01
    • 2023-04-07
    • 2021-03-20
    • 2021-08-10
    • 2021-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多