首页 文章

使用特定数字替换行中的最大值,并使用dplyr基于该最大值替换同一行中的所有其他值

提问于
浏览
1

我有一个由问卷数据组成的数据框,每列代表问卷上的一个项目 .

数据类似于以下内容:

df <- data.frame(Q1a = c(3, 2, 5, 6, 9), Q1b = c(2, 0, -2, 0, 9), Q2a = c(1, 4, 7, 2, 4), 
             Q2b = c(0, 0, -1, 0, 0), Q3a = c(5, 7, 2, 0, 9), Q3b = c(-2, -2, 3, 6, 9),
             Q4a = c(5, 2, 4, 9, 0), Q4b = c(0, 0, -2, -2, -2))

每个问卷项目有两个版本(a,b) . 我想选择所有带有“b”后缀的项目 . 对于那些带有“b”后缀的列,我想将值为-2的单元格数除以该特定列中非空白和非NA的总数 . 我想对所有列重复上述过程 . 我设法用以下代码完成它:

test <- df %>%
  select(ends_with("b")) %>%
  mutate_all(funs(round(sum(. == -2)/sum(. != "" | . != NA)*100, 
                        digits = 2)))

因为我知道没有"group_by"等效于列而不是行,所以在上面输出的每一行中重复相同的结果 . 我已设法使用以下代码删除带有 slice 的重复信息的行:

test <- df %>%
  select(ends_with("b")) %>%
  mutate_all(funs(round(sum(. == -2)/sum(. != "" | . != NA)*100, 
                        digits = 2))) %>%
  slice(1)

通过上面的输出,我想继续我的dplyr管道,将该行中的最大值替换为值1,将所有其他值替换为最大值的百分比 .

我所拥有的是以下内容:

Before

我想要的输出是:

After

我的两个问题是:

1) . 是否有一个group_by等效的列适用于列?如果是这样,我就不必以如此笨拙的方式使用 slice .

2) . 有人可以帮我完成我的dplyr管道到我想要的输出吗?我不知道如何从那里开始 .

谢谢!

2 回答

  • 1

    最好以长格式处理数据 . 但是如果data.frame中存在 3000+ 列,并且OP希望以宽格式本身处理数据,那么一个解决方案可以是使用 dplyr::summarise_all 而不是OP使用的 mutate_all

    library(dplyr)
    
    df %>%
      select(ends_with("b")) %>%
      summarise_all(funs(round(sum(. == -2)/sum(!is.na(.))*100, 
                            digits = 2))) %>%
      mutate(maxV = max(.)) %>%
      mutate_all(funs(100*./maxV)) %>%
      select(-maxV)
    
    #     Q1b Q2b   Q3b Q4b
    # 1 33.33   0 66.67 100
    
  • 3

    首先,以长格式收集数据,然后过滤NA和0值 . 比你可以分组和总结 .

    library(tidyverse)
    df %>%
      select(ends_with("b")) %>%
      gather() %>%
      filter( !value == 0 | is.na( value ) ) %>%
      group_by( key ) %>%
      summarise( output = round( 100 * length( value[value == -2] ) / n(), digits = 1 ) )
    
    # # A tibble: 4 x 2
    # key   output
    # <chr>  <dbl>
    # 1 Q1b     33.3
    # 2 Q2b      0  
    # 3 Q3b     40  
    # 4 Q4b    100
    

    请注意,Q3b的结果与您想要的输出不同 . 您确定所需的输出是否正确?

相关问题