【问题标题】:spliting a data.frame to a list of smaller data.frames containing a pair将数据框拆分为包含一对的较小数据框列表
【发布时间】:2021-12-06 22:26:16
【问题描述】:

我想知道如何在下面拆分我的data,以便我得到一个较小的dataf.rames 列表,其中每个都包含一对独特的type

我的desired_output 如下所示。

请注意,这只是一个玩具数据,因此type 可以是任何其他变量。另外,请注意,如果特定的 type 只有一行(如 type == 4),我想通过警告排除它:

type 4 has just one row thus is excluded.

m=
"
  obs   type
    1   1
    2   1
    3   a
    4   a
    5   3
    6   3
    7   4
"
data <- read.table(text = m, h=T)


desired_output <-list(
  
  data.frame(obs=1:4,   type=c(1,1,"a","a")),
  
  data.frame(obs=c(1,2,5,6),   type=c(1,1,3,3)),
  
  data.frame(obs=3:6,   type=c("a","a",3,3))
)

# warning: type 4 has just one row thus is excluded.

【问题讨论】:

    标签: r dataframe function dplyr tidyverse


    【解决方案1】:

    这里是基本 R 函数 -

    return_list_data <- function(data, type) {
      unique_counts <- table(data[[type]])
      single_count <- names(unique_counts[unique_counts == 1])
      if(length(single_count)) {
        warning(sprintf('%s %s has just one row thus is excluded.', type, toString(single_count)))
      }
      multiple_count <- names(unique_counts[unique_counts > 1])
      
      combn(multiple_count, 2, function(x) {
        data[data[[type]] %in% x, ]
      }, simplify = FALSE)  
    }
    

    这会返回 -

    return_list_data(data, 'type')
    
    #[[1]]
    #  obs type
    #1   1    1
    #2   2    1
    #5   5    3
    #6   6    3
    
    #[[2]]
    #  obs type
    #1   1    1
    #2   2    1
    #3   3    a
    #4   4    a
    
    #[[3]]
    #  obs type
    #3   3    a
    #4   4    a
    #5   5    3
    #6   6    3
    
    #Warning message:
    #In return_list_data(data, "type") :
    #  type 4 has just one row thus is excluded.
    

    如果没有单行的type,即return_list_data(data[-7, ], 'type'),则不会生成警告。

    【讨论】:

    • 当然,type 可以是可变的,但您的问题不包括该信息。
    • 你可以把最后一行改成setNames(combn(multiple_count, 2, function(x) { data[data[[type]] %in% x, ] }, simplify = FALSE), combn(multiple_count, 2, paste, collapse = '-'))
    • 嗨 Ronak,你知道this function question 的答案吗?
    【解决方案2】:

    您可以尝试使用dplyr

    df1 <- read.table(text = m, h=T)
    fun <- function(df1){
      df2 <- df1 %>%
        group_by(type) %>%
        filter(n() > 1) 
      
      df3 <- combn(unique(df2$type), 2) %>% as.data.frame
      
      df4 <- lapply(df3, function(x){
        df2 %>%
          filter(type %in% x)
      })
      war <- df1 %>%
        group_by(type) %>%
        filter(n()<= 1) %>%
        pull(type)%>%
        unique
      if (length(war)>0){
      warning(paste("type", war, "has just one row thus is excluded"))}
      return(df4)
    }
    fun(df1)
    

    结果:

    $V1
    # A tibble: 4 x 2
    # Groups:   type [2]
        obs type 
      <int> <chr>
    1     1 1    
    2     2 1    
    3     3 a    
    4     4 a    
    
    $V2
    # A tibble: 4 x 2
    # Groups:   type [2]
        obs type 
      <int> <chr>
    1     1 1    
    2     2 1    
    3     5 3    
    4     6 3    
    
    $V3
    # A tibble: 4 x 2
    # Groups:   type [2]
        obs type 
      <int> <chr>
    1     3 a    
    2     4 a    
    3     5 3    
    4     6 3 
    Warnings: In fun(df1) : type 4 has just one row thus is excluded
    

    【讨论】:

      猜你喜欢
      • 2022-01-02
      • 1970-01-01
      • 1970-01-01
      • 2019-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-22
      • 1970-01-01
      相关资源
      最近更新 更多