代码之家  ›  专栏  ›  技术社区  ›  DTYK

使用mutate-at重新编码多个列值,并基于管道中的mutated列创建新列

  •  0
  • DTYK  · 技术社区  · 7 年前

    我有一个宽格式的问卷数据框架,每一列代表一个问卷项目。

    我知道如何重新编码列中的值,并根据在其他列中找到的值创建新列。然而,我在尝试在一个管道中同时做这两件事时遇到了问题。

    我的数据如下:

    df <- data.frame(Q1 = c(1, 2, 1, 4), Q2 = c(4, 2, 3, 1), Q3 = c(3, 3, 2, 3),
                 Q4 = c(4, 4, 2, 4), Q5 = c(4, 2, 3, 1), Q6 = c(7, 2, 3, 1))
    

    以我的示例数据集为例,我打算从列Q1、Q2和Q3中减去1,并用新的(减去的)值替换原始值同时,我希望创建一个新列,其中包含Q1、Q2和Q3的平均值,同时忽略任何NA值或3的值。

    我尝试了下面的代码,但是Q1、Q2和Q3列没有用减去的值更新。

    library(dplyr)
    
    df$mean <- df %>%
      select(Q1, Q2, Q3) %>%
      mutate_all(funs(. - 1)) %>%
      apply(1, function(x) {
        round(mean(x[!is.na(x) & x != 3]), digits = 2)
      })
    

    我试过用 mutate_at 然后 mutate 在管子里但是,最终结果会删除所有未选中的列。我仍然希望其他列位于最终数据集中:

    df <- df %>%
      select(Q1, Q2, Q3) %>%
      mutate_all(funs(. - 1)) %>%
      mutate(mean = apply(., 1, function(x)
        round(mean(x[!is.na(x) & x != 3]), digits = 2)))
    

    谢谢,非常感谢!

    2 回复  |  直到 7 年前
        1
  •  1
  •   MeetMrMet    7 年前

    我们可以定义要对其执行操作的变量向量,然后在 mutate_at 做减法运算就平均而言,我们可以 select apply 你已经有了

    subtract <- c("Q1", "Q2", "Q3")
    df2 <- df %>%
      mutate_at(subtract, funs(. - 1)) %>%
      mutate(mean = apply(select(., one_of(subtract)), 1, function(x)
        round(mean(x[!is.na(x) & x != 3]), digits = 2)))
    
    df2
    #   Q1 Q2 Q3 Q4 Q5 Q6 mean
    # 1  0  3  2  4  4  7 1.00
    # 2  1  1  2  4  2  2 1.33
    # 3  0  2  1  2  3  3 1.00
    # 4  3  0  2  4  1  1 1.00
    
        2
  •  1
  •   Ronak Shah    7 年前

    一个选择是我们 select 所需的列,从每个列中减去-1,然后 mean , rowwise 从这些列中添加新列。

    library(tidyverse)
    
    df %>%
      select(1:3) %>%
      mutate_all(funs(. - 1)) %>%
      rowwise() %>%
      do( (.) %>% as.data.frame %>% 
          mutate(mean = mean(.[. != 3], na.rm = TRUE)))
    
    #    Q1    Q2    Q3  mean
    #* <dbl> <dbl> <dbl> <dbl>
    #1  0     3.00  2.00  1.00
    #2  1.00  1.00  2.00  1.33
    #3  0     2.00  1.00  1.00
    #4  3.00  0     2.00  1.00
    

    也可以写成

    (df[1:3] - 1) %>%
        rowwise() %>%
        do( (.) %>% as.data.frame %>% 
        mutate(mean = mean(.[. != 3], na.rm = TRUE)))
    

    或者完全避免 do 调用我们可以创建一个函数来计算 意思是 应用它 顺时针

    apply_fun <- function(x) {
      mean(x[x != 3], na.rm = TRUE)
    }
    
    (df[1:3] - 1) %>%
      rowwise() %>%
      mutate(mean = apply_fun(c(Q1, Q2, Q3)))
    
     #    Q1    Q2    Q3  mean
     #  <dbl> <dbl> <dbl> <dbl>
     #1  0     3.00  2.00  1.00
     #2  1.00  1.00  2.00  1.33
     #3  0     2.00  1.00  1.00
     #4  3.00  0     2.00  1.00