【问题标题】:R split a character string into multiple columns when have different string lengths, dplyr当字符串长度不同时,R将字符串拆分为多列,dplyr
【发布时间】:2020-06-08 00:08:36
【问题描述】:

我有动物跟踪数据,其中随着时间的推移遇到了每只动物,并在每次遭遇时记录了性别。遭遇分为三种类型(type1、type2 和 type3)。每行代表一种动物,每次遭遇被分类为 M(雄性)或 F(雌性)。类型中的每个字符都代表一次遭遇(例如,MMMM 是一种动物,见过四次,每次都记录为雄性)。

样本数据:

animal.ID    type1         type2       type3
1            MMMMMMM       M           M
2            MFMM          M           M
3            FFM           F           F
4            FFFFFFFFF     F           F  
5            MM            M           M

我想知道每只动物的性别(雄性还是雌性)记录是否一致。

我想制作这样的东西,其中一列指示性别是否始终如一地记录 (1) 或不 (0)。

animal.ID    type1         type2       type3    consistent
1            MMMMMMM       M           M         1
2            MFMM          M           M         0
3            FFM           F           F         0
4            FFFFFFFFF     F           F         1
5            MM            M           M         1

我可以使用 if_else 来获取 type2 和 type3 数据的“一致”列:

df %>%
   mutate(consistent = if_else(type2 == type3), 1, 0))

但是,我不能包含 type1 数据,因为它在每个字符串中有多个字符,并且每个字符串中的字符数不同。

一种方法是使用 str_split 将 type1 拆分为多个列,但是,鉴于每个字符串中的字符数不同,我不知道如何做到这一点。

【问题讨论】:

    标签: r dplyr tidyverse stringr stringi


    【解决方案1】:

    一种方法可能是使用strsplitunlist,检查所有字符是否等于type2(除了检查type2 是否等于type3)。

    df %>%
      rowwise() %>%
      mutate(consistent = ifelse(type2 == type3 & all(unlist(strsplit(type1, "")) == type2), 1, 0))
    

    输出

    # A tibble: 5 x 5
      animal.ID type1     type2 type3 consistent
          <int> <chr>     <chr> <chr>      <dbl>
    1         1 MMMMMMM   M     M              1
    2         2 MFMM      M     M              0
    3         3 FFM       F     F              0
    4         4 FFFFFFFFF F     F              1
    5         5 MM        M     M              1
    

    【讨论】:

      【解决方案2】:

      我们可以使用charToRaw 来获得type1 的“原始”表示,如果它们都相同则赋值为1。

      df$consistent <- +(sapply(df$type1, function(x) length(unique(charToRaw(x)))) ==1)
      

      使用dplyr,我们可以使用相同的逻辑:

      library(dplyr)
      
      df %>%
        rowwise() %>%
        mutate(consistent = +(n_distinct(charToRaw(type1)) == 1))
      
      
      #  animal.ID type1     type2 type3 consistent
      #      <int> <chr>     <chr> <chr>      <int>
      #1         1 MMMMMMM   M     M              1
      #2         2 MFMM      M     M              0
      #3         3 FFM       F     F              0
      #4         4 FFFFFFFFF F     F              1
      #5         5 MM        M     M              1
      

      数据

      df <- structure(list(animal.ID = 1:5, type1 = c("MMMMMMM", "MFMM", 
      "FFM", "FFFFFFFFF", "MM"), type2 = c("M", "M", "F", "F", "M"), 
      type3 = c("M", "M", "F", "F", "M")), class = "data.frame", row.names = c(NA, -5L))
      

      【讨论】:

        【解决方案3】:

        另一个使用逻辑的解决方案@Ronak Shah

        library(tidyverse)
        df %>% 
              unite("all_type", starts_with("type"), sep = "", remove = F) %>% 
              mutate(consistent = map(strsplit(all_type, ""), ~ +(n_distinct(.x) == 1)))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-11-20
          • 1970-01-01
          • 2021-10-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多