【问题标题】:How do you keep the first value in multiple columns?您如何将第一个值保留在多列中?
【发布时间】:2019-11-27 22:03:11
【问题描述】:

我有一个数据框。我想将第一个值保留在多个列中。

我更喜欢使用管道 %>% 运算符的 tidyverse 解决方案。我更喜欢可以输入 E1:N3 的解决方案,因为我在真实数据集中有大约 50 列。

这是数据框:

df <- data.frame(age = c(20, 25, 30), E1 = c("1 Alpha", "2 Bravo", "1 Alpha"), E2 = c("2 Bravo", "2 Bravo", "2 Bravo"), E3 = c("1 Alpha", "2 Bravo", "2 Bravo"), N1 = c("1 Alpha", "1 Alpha", "1 Alpha"), N2 = c("2 Bravo", "1 Alpha", "2 Bravo"), N3 = c("2 Bravo", "2 Bravo", "1 Alpha"))
df
#>   age      E1      E2      E3      N1      N2      N3
#> 1  20 1 Alpha 2 Bravo 1 Alpha 1 Alpha 2 Bravo 2 Bravo
#> 2  25 2 Bravo 2 Bravo 2 Bravo 1 Alpha 1 Alpha 2 Bravo
#> 3  30 1 Alpha 2 Bravo 2 Bravo 1 Alpha 2 Bravo 1 Alpha

这就是我想要的:

df_expected <- data.frame(age = c(20, 25, 30), E1 = c("1", "2", "1"), E2 = c("2", "2", "2"), E3 = c("1", "2", "2"), N1 = c("1", "1", "1"), N2 = c("2", "1", "2"), N3 = c("2", "2", "1"))
df_expected
#>   age E1 E2 E3 N1 N2 N3
#> 1  20  1  2  1  1  2  2
#> 2  25  2  2  2  1  1  2
#> 3  30  1  2  2  1  2  1

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    你也可以这样做:

    df %>%
     mutate_at(vars(E1:N3), ~ substr(., 1, 1))
    
      age E1 E2 E3 N1 N2 N3
    1  20  1  2  1  1  2  2
    2  25  2  2  2  1  1  2
    3  30  1  2  2  1  2  1
    

    然后,如果它总是数字并且您正在寻找数字向量,您可以这样做:

    df %>%
     mutate_at(vars(E1:N3), ~ as.numeric(substr(., 1, 1)))
    

    【讨论】:

      【解决方案2】:

      这是一个选项,用于在列名称中以“E”或“N”开头的列中提取第一个带有parse_number 的数字部分,后跟一个或多个数字 (\\d+)

      library(dplyr)
      library(stringr)
      df %>%
         mutate_at(vars(matches("^(E|N)\\d+$")), ~readr::parse_number(as.character(.)))
      

      或使用str_remove 删除从一个或多个空格开始的子字符串,包括其他字符(.*

      df %>%
         mutate_at(vars(-age), ~ str_remove(., "\\s+.*"))
      #   age E1 E2 E3 N1 N2 N3
      #1  20  1  2  1  1  2  2
      #2  25  2  2  2  1  1  2
      #3  30  1  2  2  1  2  1
      

      或使用base R

      df[-1] <- lapply(df[-1], sub, pattern = "\\s.*", replacement = "")
      

      【讨论】:

      • 我真的很喜欢最初的解决方案。谢谢你。 df %>% mutate_at(vars(starts_with("E"), (starts_with("N"))), ~readr::parse_number(as.character(.)))
      【解决方案3】:

      我们也可以使用正则表达式来提取第一个字符

      library(dplyr)
      
      df %>%
        mutate_at(vars(E1:N3), ~stringr::str_extract(., ".")) %>% 
        mutate_all(as.numeric)
      
      #  age E1 E2 E3 N1 N2 N3
      #1  20  1  2  1  1  2  2
      #2  25  2  2  2  1  1  2
      #3  30  1  2  2  1  2  1
      

      或类似的概念使用sub

      df %>%
        mutate_at(vars(E1:N3), ~sub("(.).*", "\\1", .)) %>%
        mutate_all(as.numeric)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-09-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-10
        • 2015-04-26
        相关资源
        最近更新 更多