【问题标题】:Condense Duplicate Rows into Unique Rows with if使用 if 将重复的行压缩成唯一的行
【发布时间】:2018-07-17 10:02:59
【问题描述】:

所以有一种情况:

数据帧:

dat <- data.frame(colA = rep(c(0,1,0), c(6,1,8)), 
                  colB = rep(c(1,0,1,0), c(1,4,1,9)), 
                  colC = rep(c(0,1,0), c(9,1,5)), 
                  colD = rep(c(0,1,0), c(8,1,6)), 
                  colE = rep(0, 15), 
                  color = rep(c("blue","red","yellow"), each=5), 
                  colorId = rep(c(22,40,35), each=5))

colA   colB    colC    colD   colE   color   colorId
0      1       0       0      0      Blue    22
0      0       0       0      0      Blue    22
0      0       0       0      0      Blue    22
0      0       0       0      0      Blue    22
0      0       0       0      0      Blue    22
0      1       0       0      0      Red     40
1      0       0       0      0      Red     40
0      0       0       0      0      Red     40
0      0       0       1      0      Red     40
0      0       1       0      0      Red     40
0      0       0       0      0      Yellow  35
0      0       0       0      0      Yellow  35
0      0       0       0      0      Yellow  35
0      0       0       0      0      Yellow  35
0      0       0       0      0      Yellow  35

最终目标

colNames      color   colorId
colB          Blue    22
colB          Red     40
colA          Red     40
colD          Red     40
colC          Red     40
None          Yellow  35

这是我开始采用的方法,然后我疑惑地质疑自己。下面未显示,我创建了另一列,它使用 rowSums (dat$rowsu

我正在考虑编写一个函数,如果 colorId 重复计数超过 0 个,则保留 rowsu > 0 的任何行,在特殊情况下为黄色,如果它们都是 0 并且整体 rowsu = 0,然后在所有重复项中保留一行,类似于下面的内容。 (如果是这个问题,在编码这部分时会遇到麻烦)

colA   colB    colC    colD   colE   color   colorId
0      1       0       0      0      Blue    22
0      1       0       0      0      Red     40
1      0       0       0      0      Red     40
0      0       0       1      0      Red     40
0      0       1       0      0      Red     40
0      0       0       0      0      Yellow  35

其次,对于后一个用名称创建列的问题,是否还在考虑一个 if 函数,如果它下面有一个 1,则使用 colname 名称将其提取到行名称中?不确定。

【问题讨论】:

    标签: r dataframe conditional-statements


    【解决方案1】:

    data.table-package 的可能解决方案:

    library(data.table)
    setDT(dat)[, .(colNames = {cs <- colSums(.SD == 1) > 0;
                               if(sum(cs) > 0) names(.SD)[cs] else 'None'})
               , by = .(color, colorId)]
    

    给出:

        color colorId colNames
    1:   blue      22     colB
    2:    red      40     colA
    3:    red      40     colB
    4:    red      40     colC
    5:    red      40     colD
    6: yellow      35     None
    

    这是做什么的:

    • setDT(dat)dat 转换为 'data.table'(它是 data.frame 的增强形式)。
    • data.tble-syntax 与 dat[i, j, by] (see 1b for an explanation) 类似。在这种情况下,datcolorcolorIdby = .(color, colorId)-部分)分组。
    • 对于每个组,colSums(.SD == 1) &gt; 0 检查colAcolE 列是否包含1。生成的逻辑向量临时存储为cs.SD 代表 SData 的子集(参见上一点链接下的 2b)。
    • 最后,我们检查是否至少有一列有1sum(cs) &gt; 0。如果是这种情况,则names(.SD)[cs] 返回相应的列名,如果条件不成立,则返回None

    使用tidyverse 中的dplyr,您可以获得相同的结果:

    library(dplyr)
    dat %>% 
      group_by(color, colorId) %>% 
      do(data.frame(colNames = {cs <- colSums(. == 1) > 0;
                                if(sum(cs) > 0) names(.)[cs] else 'None'}))
    

    【讨论】:

    • 谢谢@Jaap!工作完美。可以通过它的工作原理来分解这段代码吗?
    • @S31 添加了解释,HTH。
    【解决方案2】:

    这是tidyverse 的一个选项,我们gather 将列'colA' 到'colE' 转换为长格式,按'color'、'colorId' 分组,创建'None' 作为'colNames' @987654323 @所有的“val”都是0。如果需要,获取distinct行和filter对于“val”为1或“colNames”为“无”的行和select感兴趣的列和arrange /p>

    library(tidyverse)
    dat %>%
        mutate_at(vars(color, colorId), funs(factor(., levels = unique(.)))) %>% 
        gather(colNames, val, colA:colE) %>% 
        group_by(color, colorId) %>% 
        mutate(colNames = if(all(val==0)) "None" else colNames) %>% 
        distinct %>%
        filter(val == 1| colNames == "None") %>% 
        select(colNames, color, colorId) %>%
        arrange(color, colNames)
    # A tibble: 6 x 3
    # Groups: color, colorId [3]
    #  colNames color  colorId
    #  <chr>    <fctr> <fctr> 
    #1 colB     blue   22     
    #2 colA     red    40     
    #3 colB     red    40     
    #4 colC     red    40     
    #5 colD     red    40     
    #6 None     yellow 35     
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-07-16
      • 1970-01-01
      • 2010-10-03
      • 2020-01-26
      • 1970-01-01
      • 1970-01-01
      • 2017-02-06
      • 1970-01-01
      相关资源
      最近更新 更多