【问题标题】:Replace all values in a data frame, conditionally有条件地替换数据框中的所有值
【发布时间】:2021-10-15 06:04:57
【问题描述】:

我有一个数字数据框,我正在尝试将其中的每个值更改为一个字符串,然后按该字符串按比例对其进行汇总。

示例表:

var1 var2 var3 var4
 2    3    5    8
 3    6    8    7
 5    3    7    4

如果一个数字小于4,我想用“no”代替,如果一个数字大于或等于4,我想用“yes”代替它

然后我想总结一下每一列的“是”和“否”值的比例。

我尝试过使用 dplyr,对于单个列似乎很容易,但我在将它应用于所有列时遇到了麻烦。我尝试了这样的方法,但没有成功。

df %>%
select(var1:var4) %>%
mutate_each(funs(replace(., . < 4, "no")) %>%
mutate_each(funs(replace., . => 4, "yes")) %>%
summarise(count = n())

感谢您的帮助。

【问题讨论】:

    标签: r dataframe if-statement dplyr conditional-statements


    【解决方案1】:
    library(tidyverse)
    
    df <- data.frame(
      var1 = c(2L, 3L, 5L),
      var2 = c(3L, 6L, 3L),
      var3 = c(5L, 8L, 7L),
      var4 = c(8L, 7L, 4L)
    )
    
    df %>%
      mutate(across(.fns = ~ . >= 4)) %>%
      summarise(across(.fns = ~ sum(.)/length(.) ))
    #>        var1      var2 var3 var4
    #> 1 0.3333333 0.3333333    1    1
    

    【讨论】:

    • 谢谢!效果很好
    【解决方案2】:

    我们可以循环 across 列,将值转换为“否”、“是”,使用 pivot_longer 重塑为“长”格式,得到 count 并除以计数的 sum按“名称”分组后返回比例

    library(dplyr)
    library(tidyr)
    df %>%
          mutate(across(everything(), 
              ~ case_when(. < 4 ~ 'no', TRUE ~ 'yes'))) %>% 
          pivot_longer(everything()) %>% 
          count(name, value) %>%
          group_by(name) %>%
          mutate(prop = 100 * n/sum(n)) %>%
          ungroup
    

    -输出

    # A tibble: 6 x 4
      name  value     n  prop
      <chr> <chr> <int> <dbl>
    1 var1  no        2  66.7
    2 var1  yes       1  33.3
    3 var2  no        2  66.7
    4 var2  yes       1  33.3
    5 var3  yes       3 100  
    6 var4  yes       3 100  
    

    或使用base R

    100 * proportions(table(names(df)[col(df)], c('no', 'yes')[(df >= 4) + 1]), 1)
          
                  no       yes
      var1  66.66667  33.33333
      var2  66.66667  33.33333
      var3   0.00000 100.00000
      var4   0.00000 100.00000
    

    数据

    df <- structure(list(var1 = c(2L, 3L, 5L), var2 = c(3L, 6L, 3L), var3 = c(5L, 
    8L, 7L), var4 = c(8L, 7L, 4L)), class = "data.frame", row.names = c(NA, 
    -3L))
    

    【讨论】:

      【解决方案3】:

      这是使用 ifelsegroup_bysummarise 的 akrun 的类似答案(原版):

      df %>% 
        mutate(across(var1:var4, ~ifelse(. < 4, 'no', 'yes'))) %>% 
        pivot_longer(
          cols = starts_with("var")) %>% 
        group_by(name, value) %>% 
        summarise(count = n()) %>% 
        mutate(prop = count/sum(count)*100)
      

      输出:

        name  value count  prop
        <chr> <chr> <int> <dbl>
      1 var1  no        2  66.7
      2 var1  yes       1  33.3
      3 var2  no        2  66.7
      4 var2  yes       1  33.3
      5 var3  yes       3 100  
      6 var4  yes       3 100  
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-03-14
        • 2020-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-10
        • 1970-01-01
        相关资源
        最近更新 更多