【问题标题】:Subset large dataframe over distinct singular character variable column value在不同的单数字符变量列值上对大数据帧进行子集化
【发布时间】:2023-02-21 16:33:21
【问题描述】:

我仍在学习 R 并且想知道我是否有一种优雅的方式来操纵下面的 df 来实现 df2。

我不确定它是否应该用于此循环,但基本上我想对每个 V(X)_ID 和它关联的 V(X)_Z 进行区分并返回第一行 V(X) _ID 以及随后出现的每隔一个 V(X)_Z(只有两种不同类型的 V(X)_Z)。

这可能听起来令人困惑,所以希望从 df 到所需 df2 的示例将有助于可视化我要问的内容。

V1_ID <- c('A','B','I','N','G') 
V1_X <- c(1,2,3,4,5) 
V1_Y <- c(5.1,4.2,3.2,2.1,6.1) 
V1_Z <- c('Tom','Tom','Bill','Tom','Tom')

V2_ID <- c('B','D','E','F','G') 
V2_X <- c(2,5,6,7,5) 
V2_Y <- c(4.2,2,1,9,6.1) 
V2_Z <- c('Tom','Tom','Tom','Tom','Tom')

V3_ID <- c('C','B','A','N','G') 
V3_X <- c(0,2,1,4,5) 
V3_Y <- c(3,4.2,5.1,2.1,6.1) 
V3_Z <- c('Bill','Bill','Bill','Tom','Tom')

V4_ID <- c('N','G','C','B','A') 
V4_X <- c(4,5,0,2,1) 
V4_Y <- c(2,6.1,3,4.2,5.1) 
V4_Z <- c('Tom','Tom','Bill','Bill','Bill')

df <-data.frame(V1_ID,V1_X,V1_Y,V1_Z,V2_ID,V2_X,V2_Y,V2_Z,V3_ID,V3_X,V3_Y,V3_Z,V4_ID,V4_X,V4_Y,V4_Z)

V1_ID <- c('A','I',NA,NA) 
V1_X <- c(1,3,NA,NA) 
V1_Y <- c(5.1,3.2,NA,NA) 
V1_Z <- c('Tom','Bill',NA,NA)

V3_ID <- c('C','N','G',NA) 
V3_X <- c(0,4,5,NA) 
V3_Y <- c(3,2.1,6.1,NA) 
V3_Z <- c('Bill','Tom','Tom',NA)

V4_ID <- c('N','C','B','A') 
V4_X <- c(4,0,2,1) 
V4_Y <- c(2,3,4.2,5.1) 
V4_Z <- c('Tom','Bill','Bill','Bill')

df2 <- data.frame(V1_ID,V1_X,V1_Y,V1_Z,V3_ID,V3_X,V3_Y,V3_Z,V4_ID,V4_X,V4_Y,V4_Z)

您可以看到 V2 已从所需的数据帧中排除,因为除了“Tom”之外没有出现其他不同的 V2_Z。

非常感谢您的帮助,因为我有数百种此类格式的列,并且从手动的角度来看它是非常耗费精力的。

谢谢

【问题讨论】:

    标签: r dplyr tidyr rbind mutate


    【解决方案1】:

    我认为最好先以长格式提供这些数据,然后再考虑要过滤的内容。以下是第一种方法,也许您可​​以详细说明要过滤的确切条件。

    library(tidyverse)
    
    # lets get the variable stems
    suf <- unique(gsub("V\d_(.*)", "\1", names(df)))
    
    # lets loop over the number of V variables and append each data.frame as rows
    df_long <- map(paste0("V", 1:4),
        ~ select(df, all_of(setNames(paste0(.x, "_", suf), suf)))) %>% 
      bind_rows(.id = "no")
    
    df_long %>%
      group_by(no) %>% 
      # here we filter all groups `no` which only have one value in `Z`:
      filter(n_distinct(Z) > 1) %>% 
      # is this the condition you want to filter by?
      distinct(no, Z, .keep_all = TRUE) 
    
    #> # A tibble: 6 x 5
    #> # Groups:   no [3]
    #>   no    ID        X     Y Z    
    #>   <chr> <chr> <dbl> <dbl> <chr>
    #> 1 1     A         1   5.1 Tom  
    #> 2 1     I         3   3.2 Bill 
    #> 3 3     C         0   3   Bill 
    #> 4 3     N         4   2.1 Tom  
    #> 5 4     N         4   2   Tom  
    #> 6 4     C         0   3   Bill
    

    来自 OP 的数据

    V1_ID <- c('A','B','I','N','G') 
    V1_X <- c(1,2,3,4,5) 
    V1_Y <- c(5.1,4.2,3.2,2.1,6.1) 
    V1_Z <- c('Tom','Tom','Bill','Tom','Tom')
    
    V2_ID <- c('B','D','E','F','G') 
    V2_X <- c(2,5,6,7,5) 
    V2_Y <- c(4.2,2,1,9,6.1) 
    V2_Z <- c('Tom','Tom','Tom','Tom','Tom')
    
    V3_ID <- c('C','B','A','N','G') 
    V3_X <- c(0,2,1,4,5) 
    V3_Y <- c(3,4.2,5.1,2.1,6.1) 
    V3_Z <- c('Bill','Bill','Bill','Tom','Tom')
    
    V4_ID <- c('N','G','C','B','A') 
    V4_X <- c(4,5,0,2,1) 
    V4_Y <- c(2,6.1,3,4.2,5.1) 
    V4_Z <- c('Tom','Tom','Bill','Bill','Bill')
    
    df <-data.frame(V1_ID,V1_X,V1_Y,V1_Z,V2_ID,V2_X,V2_Y,V2_Z,V3_ID,V3_X,V3_Y,V3_Z,V4_ID,V4_X,V4_Y,V4_Z)
    

    reprex package (v2.0.1) 创建于 2023-02-21

    【讨论】:

      猜你喜欢
      • 2019-11-13
      • 1970-01-01
      • 2011-11-26
      • 2021-06-25
      • 1970-01-01
      • 2020-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多