【问题标题】:Keep values in single row of a column based on two boolean column values in R根据 R 中的两个布尔列值将值保留在列的单行中
【发布时间】:2020-07-16 15:37:30
【问题描述】:

我在下面举个例子来理解这个问题

我必须根据“之前”和“之后”列将“已解决”列更改为输入数据框下方。如果前列为 TRUE,后列为 FALSE,则“已解决”列应在每个“坐”列组末尾的一行中包含“名称”列的所有名称。

输入数据框:

id  name    sect    sit    before    after    
23  name23  sec34   sit34  TRUE      FALSE 
28  name28  sec13   sit89  FALSE     FALSE    
12  name12  sec13   sit34  FALSE     FALSE
76  name76  sec45   sit34  FALSE     TRUE     
45  name45  sec56   sit56  FALSE     FALSE       
145 name14  sec65   sit34  TRUE      FALSE
90  name90  sec74   sit56  FALSE     FALSE   
15  name15  sec89   sit89  TRUE      FALSE 
78  name78  sec45   sit56  FALSE     FALSE

预期结果:

id  name    sect    sit    before    after    solved
23  name23  sec34   sit34  TRUE      FALSE     
12  name12  sec13   sit34  FALSE     FALSE
145 name14  sec65   sit34  TRUE      FALSE    
76  name76  sec45   sit34  FALSE     TRUE     name23,name14
45  name45  sec56   sit56  FALSE     FALSE    
78  name78  sec45   sit56  FALSE     FALSE
90  name90  sec74   sit56  FALSE     FALSE    nothing here  
15  name15  sec89   sit89  TRUE      FALSE     
28  name28  sec13   sit89  FALSE     FALSE    name15

【问题讨论】:

  • 如何定义每个sit 列组的结尾? name最大的那一行?

标签: r


【解决方案1】:

dplyr解决方案

library(dplyr)

df %>%
  group_by(sit) %>%
  arrange(name, .by_group = T) %>% 
  mutate(solved = if_else(row_number() == n(),
                          toString(name[before > after]),
                          NA_character_))

# A tibble: 9 x 7
# Groups:   sit [3]
     id name   sect  sit   before after  solved          
  <int> <fct>  <fct> <fct> <lgl>  <lgl>  <chr>           
1    12 name12 sec13 sit34 FALSE  FALSE  NA             
2   145 name14 sec65 sit34 TRUE   FALSE  NA             
3    23 name23 sec34 sit34 TRUE   FALSE  NA             
4    76 name76 sec45 sit34 FALSE  TRUE   "name14, name23"
5    45 name45 sec56 sit56 FALSE  FALSE  NA             
6    78 name78 sec45 sit56 FALSE  FALSE  NA             
7    90 name90 sec74 sit56 FALSE  FALSE  ""              
8    15 name15 sec89 sit89 TRUE   FALSE  NA             
9    28 name28 sec13 sit89 FALSE  FALSE  "name15"   

【讨论】:

    【解决方案2】:

    试试这个:

    #Data
    df <- structure(list(id = c(23L, 28L, 12L, 76L, 45L, 145L, 90L, 15L, 
    78L), name = structure(c(4L, 5L, 1L, 7L, 6L, 2L, 9L, 3L, 8L), .Label = c("name12", 
    "name14", "name15", "name23", "name28", "name45", "name76", "name78", 
    "name90"), class = "factor"), sect = structure(c(2L, 1L, 1L, 
    3L, 4L, 5L, 6L, 7L, 3L), .Label = c("sec13", "sec34", "sec45", 
    "sec56", "sec65", "sec74", "sec89"), class = "factor"), sit = structure(c(1L, 
    3L, 1L, 1L, 2L, 1L, 2L, 3L, 2L), .Label = c("sit34", "sit56", 
    "sit89"), class = "factor"), before = c(TRUE, FALSE, FALSE, FALSE, 
    FALSE, TRUE, FALSE, TRUE, FALSE), after = c(FALSE, FALSE, FALSE, 
    TRUE, FALSE, FALSE, FALSE, FALSE, FALSE)), class = "data.frame", row.names = c(NA, 
    -9L))
    
    #Code
    #Split
    List <- split(df,df$sit)
    #Create function
    compute <- function(x)
    {
      x$Fill <- NA
      index <- which(x$before==T & x$after==F)
      x$Fill[dim(x)[1]] <- ifelse(length(index)!=0,paste(x$name[index],collapse = ','),NA)
      return(x)
    }
    #Apply
    List2 <- lapply(List,compute)
    #Bind all
    DF <- do.call(rbind,List2)
    rownames(DF)<-NULL
    
       id   name  sect   sit before after          Fill
    1  23 name23 sec34 sit34   TRUE FALSE          <NA>
    2  12 name12 sec13 sit34  FALSE FALSE          <NA>
    3  76 name76 sec45 sit34  FALSE  TRUE          <NA>
    4 145 name14 sec65 sit34   TRUE FALSE name23,name14
    5  45 name45 sec56 sit56  FALSE FALSE          <NA>
    6  90 name90 sec74 sit56  FALSE FALSE          <NA>
    7  78 name78 sec45 sit56  FALSE FALSE          <NA>
    8  28 name28 sec13 sit89  FALSE FALSE          <NA>
    9  15 name15 sec89 sit89   TRUE FALSE        name15
    

    【讨论】:

    • 从预期输出来看,name23,name14 位于name76 行,name15 位于name28 行。
    • @DarrenTsai 这取决于数据的排列方式,我认为这不是问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-27
    • 1970-01-01
    • 1970-01-01
    • 2012-05-03
    • 2020-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多