【问题标题】:Separate columns with constant numbers and condense them to one row in R data.frame用常数分隔列并将它们压缩为 R data.frame 中的一行
【发布时间】:2020-02-07 03:13:44
【问题描述】:

我有一个名为d 的data.frame。在此 data.frame 中,某些列由跨第一列的行的常量组成:study.name(见下文)。

例如,ESLESL.1profprof.1 列对于 Shin.Ellis 的所有行都是常量,对于 Trus.Hsu 的所有行也是常量,依此类推。

问: 在BASE R中,如何将这些常量变量分开,然后将它们压缩成一行只有一个数字?

我想要的输出如下所示。功能性答案表示赞赏。

d <- read.csv("https://raw.githubusercontent.com/izeh/m/master/irr.csv", h = T)[-(2:3)]

## FIRST 8 ROWS:

#    study.name ESL prof scope type ESL.1 prof.1 scope.1 type.1
# 1  Shin.Ellis   1    2     1    1     1      2       1      1
# 2  Shin.Ellis   1    2     1    1     1      2       1      1
# 3  Shin.Ellis   1    2     1    2     1      2       1      1
# 4  Shin.Ellis   1    2     1    2     1      2       1      1
# 5  Shin.Ellis   1    2    NA   NA     1      2      NA     NA
# 6  Shin.Ellis   1    2    NA   NA     1      2      NA     NA
# 7    Trus.Hsu   2    2     2    1     2      2       1      1
# 8    Trus.Hsu   2    2    NA   NA     2      2      NA     NA

期望的输出:

#    study.name ESL prof  ESL.1 prof.1 
# 1  Shin.Ellis   1    2      1      2  
# 2  Trus.Hsu     2    2      2      2
# .     .         .    .      .      . # AND SO ON !!!

【问题讨论】:

    标签: r function loops dataframe


    【解决方案1】:

    如果您只想删除所有列中的重复值 unique() is base R

    unique(d)
    

    编辑 - 感谢@CalumYou 的澄清 - 我认为这就是 OP 在基础 R 中寻找的内容。

    is_constant = lapply(split(d, d$study.name), function(data){
      unlist(lapply(data,function(col){
        length(unique(col)) == 1
      }))
    })
    is_constant = as.data.frame(do.call(rbind, is_constant))
    all_constant = d[,unlist(lapply(is_constant,all))]
    all_constant = unique(all_constant)
    

    【讨论】:

    • 这似乎不是 OP 的问题,他们想弄清楚哪些列是按组保持不变的,对于所有组
    • @CalumYou,谢谢您的回答。这正是我所追求的。
    【解决方案2】:

    也许我们需要

    library(dplyr)
    d %>%
       group_by(study.name) %>%
       slice(1)
    

    或者在base R中按'study.name'分组后,获取第一行,同时指定na.action = NULL作为默认选项是na.omit,它可以省略任何列中具有NA的行

    aggregate(.~ study.name, d, head, 1, na.action = NULL)
    

    如果我们想对列进行子集化

    nm1 <- names(which(!colSums(!do.call(rbind, by(d[-1], d$study.name,
         FUN = function(x) lengths(sapply(x, unique)) == 1)))))
    unique(d[c("study.name", nm1)])
    

    【讨论】:

    • 这不只是得到没有 NA 的第一行吗?它不会限制每个组的恒定列
    【解决方案3】:

    你可以试试这样的东西,虽然感觉有点笨拙。基本上,按组检查所有组的哪些列具有恒定值,仅保留这些列,然后仅保留 unique 值(因为现在它们按组是恒定的)。

    d <- read.table(header = TRUE,
    text = "study.name ESL prof scope type ESL.1 prof.1 scope.1 type.1
    Shin.Ellis   1    2     1    1     1      2       1      1
    Shin.Ellis   1    2     1    1     1      2       1      1
    Shin.Ellis   1    2     1    2     1      2       1      1
    Shin.Ellis   1    2     1    2     1      2       1      1
    Shin.Ellis   1    2    NA   NA     1      2      NA     NA
    Shin.Ellis   1    2    NA   NA     1      2      NA     NA
      Trus.Hsu   2    2     2    1     2      2       1      1
      Trus.Hsu   2    2    NA   NA     2      2      NA     NA")
    
    is_constant <- function(x) length(unique(x)) == 1L
    
    keep_constants <- function(df, group_col) {
      data_cols <- colnames(df)[setdiff(1:ncol(df), group_col)]
      check_df <- aggregate(df, by = list(df[[group_col]]), FUN = is_constant)
      cols_to_keep <- sapply(check_df[, -1], all)
      unique(df[, cols_to_keep])
    }
    
    keep_constants(d, 1)
    #>   study.name ESL prof ESL.1 prof.1
    #> 1 Shin.Ellis   1    2     1      2
    #> 7   Trus.Hsu   2    2     2      2
    

    reprex package (v0.3.0) 于 2019 年 10 月 9 日创建

    【讨论】:

      【解决方案4】:
      d_list <- lapply(split(d,d$study.name), 
                       #Find columns with similar values using sapply and length(unique(cols)) 
                       #then get the 1st row
                       function(x) x[1, sapply(x,function(y) length(unique(y))==1)])
      do.call('rbind.data.frame',d_list)
      
                 study.name ESL prof ESL.1 prof.1
      Bit.KnoA     Bit.KnoA   1    3     1      3
      Bit.KnoB     Bit.KnoB   1    2     1      2
      ChandlerA   ChandlerA   1    2     1      2
      Mubarak       Mubarak   2   NA     2     NA
      SheenA         SheenA   1    2     1      2
      Shin.Ellis Shin.Ellis   1    2     1      2
      Sun               Sun   2    2     2      2
      Trus.Hsu     Trus.Hsu   2    2     2      2
      

      【讨论】:

        猜你喜欢
        • 2020-02-07
        • 2020-08-18
        • 1970-01-01
        • 2020-01-02
        • 1970-01-01
        • 1970-01-01
        • 2021-10-18
        • 2015-04-27
        • 1970-01-01
        相关资源
        最近更新 更多