【问题标题】:Pasting variable name with its vector value across multiple variables将变量名称及其向量值粘贴到多个变量中
【发布时间】:2019-11-30 19:36:55
【问题描述】:

假设我有这个数据框:

library(dplyr)

set.seed(1)
df <- tibble(sol_1 = sample(1:4, 10, replace = TRUE),
             sol_2 = sample(1:4, 10, replace = TRUE))

# A tibble: 10 x 2
   sol_1 sol_2
   <int> <int>
 1     1     3
 2     4     3
 3     3     1
 4     1     1
 5     2     1
 6     1     2
 7     3     2
 8     3     2
 9     2     2
10     2     3

我想更改变量中的值以包含它们各自的变量名称,如下所示:

# A tibble: 10 x 2
         sol_1       sol_2
         <chr>       <chr>
 1     sol_1_1     sol_2_3
 2     sol_1_4     sol_2_3
 3     sol_1_3     sol_2_1
 4     sol_1_1     sol_2_1
 5     sol_1_2     sol_2_1
 6     sol_1_1     sol_2_2
 7     sol_1_3     sol_2_2
 8     sol_1_3     sol_2_2
 9     sol_1_2     sol_2_2
10     sol_1_2     sol_2_3

哪个rlang 变量会指示使用变量名作为字符串?我尝试过类似以下的事情:

mutate_at(df, vars(starts_with("sol")), ~ paste(rlang::as_string(.x), .x, sep = "_"))

但显然我使用了错误的功能。

【问题讨论】:

    标签: r dplyr rlang tidyeval


    【解决方案1】:

    另一种选择是重塑为“长”,然后在转换后将其改回“宽”

    library(dplyr)
    library(tidyr)
    library(stringr)
    df %>%
       mutate(rn = row_number()) %>% 
       pivot_longer(cols = -rn) %>% 
       mutate(value = str_c(name, value, sep="_")) %>% 
       pivot_wider(names_from = name, values_from = value) %>%
       select(-rn)
    # A tibble: 10 x 2
    #   sol_1   sol_2  
    #   <chr>   <chr>  
    # 1 sol_1_1 sol_2_3
    # 2 sol_1_4 sol_2_3
    # 3 sol_1_3 sol_2_1
    # 4 sol_1_1 sol_2_1
    # 5 sol_1_2 sol_2_1
    # 6 sol_1_1 sol_2_2
    # 7 sol_1_3 sol_2_2
    # 8 sol_1_3 sol_2_2
    # 9 sol_1_2 sol_2_2
    #10 sol_1_2 sol_2_3
    

    或使用imap

    library(purrr)
    imap(df, ~ str_c(.y, .x, sep="_"))
    

    【讨论】:

      【解决方案2】:

      您可以使用 mutate 实现相同的目的:

      library(dplyr)
          df %>% mutate(sol_1 = paste0(names(df)[1], '_', sol_1),
                        sol_2 = paste0(names(df)[2], '_', sol_2))
      

      【讨论】:

        【解决方案3】:

        使用mutate_* 很难完成这项任务,因为它只传递没有名称的列值。相反,我们可以尝试map_dfcapply

        library(dplyr)
        library(purrr)
        nms = grep("sol", names(df), value = TRUE)
        map_dfc(nms, ~transmute(df, !!quo_name(.x) := paste0(.x,'_',!!sym(.x))))
        

        使用基础 R

        df[ ,nms] = t(apply(df[,nms], 1, function(x) paste0(names(x),'_',x)))
        

        【讨论】:

          【解决方案4】:

          基础 R 解决方案:

          df[] <- lapply(seq_along(df),
          
                         function(x){df[,x] <- paste0(names(df[c(x)]), "_", unlist(df[c(x)]))})
          

          数据:

          df <- tibble(sol_1 = sample(1:4, 10, replace = TRUE),
          
                       sol_2 = sample(1:4, 10, replace = TRUE))
          

          【讨论】:

            猜你喜欢
            • 2018-11-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多