【问题标题】:aggregating columns based on commas基于逗号聚合列
【发布时间】:2018-12-10 18:23:49
【问题描述】:

我有以下数据框,我正在尝试分隔逗号并将该特定名称转换为它们自己的单独列,并指定该特定 ID 是否存在该特定列名称(由逗号分隔)。 (1 = 是,0 = 否)任何帮助将不胜感激!谢谢!

ID<- c(1,2,3,4,5,6)
Details<- c("V1,V2", "V1,V3", "V1", "V2", "V3,V4", "V2,V3" )

data.frame <- data.frame(ID, Details, stringsAsFactors=FALSE)

期望的输出:

ID<-c(1,2,3,4,5,6)
V1<-c(1,1,1,0,0,0)
V2<-c(1,0,0,1,0,1)
V3<-c(0,1,0,0,1,1)
V4<-c(0,0,0,0,1,0)

data.frame1<-data.frame(ID, V1, V2, V3, V4, stringsAsFactors=FALSE)

【问题讨论】:

    标签: r dataframe aggregation analysis


    【解决方案1】:

    使用tidyverse 包的解决方案。 dat 是您的示例数据框。 dat2 是最终的数据帧。

    library(tidyverse)
    
    dat2 <- dat %>%
      separate_rows(Details) %>%
      mutate(Value = 1L) %>%
      spread(Details, Value, fill = 0L)
    dat2
    #   ID V1 V2 V3 V4
    # 1  1  1  1  0  0
    # 2  2  1  0  1  0
    # 3  3  1  0  0  0
    # 4  4  0  1  0  0
    # 5  5  0  0  1  1
    # 6  6  0  1  1  0
    

    【讨论】:

      【解决方案2】:

      mtabulate 的一个选项来自qdapTools

      library(qdapTools)
      cbind.data.frame(ID, # or data.frame$ID
                       mtabulate(strsplit(as.character(data.frame$Details), ",")))
      # output
        ID V1 V2 V3 V4
      1  1  1  1  0  0
      2  2  1  0  1  0
      3  3  1  0  0  0
      4  4  0  1  0  0
      5  5  0  0  1  1
      6  6  0  1  1  0
      

      【讨论】:

        【解决方案3】:

        这是一个基本的 R 解决方案。我已将您的 data.frames 重命名为 data1data2

        data1 <- data.frame(ID, Details, stringsAsFactors=FALSE)
        data2 <- data.frame(ID, V1, V2, V3, V4, stringsAsFactors=FALSE)        
        
        nms <- unique(unlist(strsplit(data1$Details, ",")))
        data3 <- cbind.data.frame(ID, sapply(nms, grepl, data1$Details))
        data3[-1] <- lapply(data3[-1], as.integer)
        

        现在将data3 与您的预期结果data2 进行比较。

        all.equal(data2, data3)
        #[1] TRUE
        

        但请注意,

        identical(data2, data3)
        #[1] FALSE
        

        这是因为我使用了as.integer 并且data2 中的值属于"numeric" 类。如果这有所不同,您可以将上面的lapply 指令更改为使用as.numeric

        【讨论】:

          【解决方案4】:

          我看到的最直接的方法是为隐藏在字符串中的每个向量构建一个 data.frame 并绑定它们。 purrr 可以帮助使其非常紧凑。请注意,不需要列 ID,我将直接处理 Details

          library(purrr)
          df <- map_dfr(strsplit(Details, ","),
                        ~data.frame(t(setNames(rep(1, length(.x)), .x))))
          df[is.na(df)] <- 0
          
          #   V1 V2 V3 V4
          # 1  1  1  0  0
          # 2  1  0  1  0
          # 3  1  0  0  0
          # 4  0  1  0  0
          # 5  0  0  1  1
          # 6  0  1  1  0
          

          您还可以拆分和取消列出以获得不同的值,然后在原始向量中查找它们:

          unique_v <- unique(unlist(strsplit(Details, ",")))
          map_dfc(unique_v, ~as.numeric(grepl(.x, Details)))
          # # A tibble: 6 x 4
          #      V1    V2    V3    V4
          #   <dbl> <dbl> <dbl> <dbl>
          # 1     1     1     0     0
          # 2     1     0     1     0
          # 3     1     0     0     0
          # 4     0     1     0     0
          # 5     0     0     1     1
          # 6     0     1     1     0
          

          如果您知道列数,我们也可以进行一些脏字符串评估:

          m <- as.data.frame(matrix(0,ncol=4,nrow=6))
          eval(parse(text=paste0("m[",ID,", c(",gsub("V","",Details),")] <- 1")))
          #   V1 V2 V3 V4
          # 1  1  1  0  0
          # 2  1  0  1  0
          # 3  1  0  0  0
          # 4  0  1  0  0
          # 5  0  0  1  1
          # 6  0  1  1  0
          

          【讨论】:

            【解决方案5】:

            使用基础 R:

             xtabs(val~.,cbind.data.frame(ID=rep(ID,lengths(s<-strsplit(Details,","))),Details=unlist(s),val=1))
               Details
            ID  V1 V2 V3 V4
              1  1  1  0  0
              2  1  0  1  0
              3  1  0  0  0
              4  0  1  0  0
              5  0  0  1  1
              6  0  1  1  0
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2015-05-17
              • 1970-01-01
              • 1970-01-01
              • 2020-06-22
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多