【问题标题】:Replacing values in a data.frame that have lost their order替换 data.frame 中丢失顺序的值
【发布时间】:2021-12-12 01:56:08
【问题描述】:

在我的玩具data 中,对于每个唯一的study数字 变量(samplegroup)的顺序必须从1 开始。但是:

例如,在study 1 中,我们看到有两个唯一的sample 值(13),所以3 必须替换为2

例如,在study 2 中,我们看到有一个唯一的group 值(2),因此必须将其替换为1

study 3 中,samplegroup 似乎都可以,这意味着它们的唯一值是 12(无需替换)。

对于这个玩具data,我的想要的输出如下所示。但我很欣赏一个功能性解决方案,它可以自动替换 data.frame 中任意数量的 numeric 变量,这些变量就像我在我的玩具 data 中展示的那样失去了顺序。

m="
study sample group outcome
1      1     1       A
1      1     1       B
1      1     2       A
1      1     2       B 
1      3     1       A
1      3     1       B
1      3     2       A
1      3     2       B

2      1     2       A
2      1     2       B
2      2     2       A
2      2     2       B
2      3     2       A
2      3     2       B

3      1     1       A
3      1     1       B
3      1     2       A
3      1     2       B
3      2     1       A
3      2     1       B
3      2     2       A
3      2     2       B"

data <- read.table(text=m, h=T)

Desired_output="
study sample group outcome
1      1     1       A
1      1     1       B
1      1     2       A
1      1     2       B 
1      2     1       A
1      2     1       B
1      2     2       A
1      2     2       B

2      1     1       A
2      1     1       B
2      2     1       A
2      2     1       B
2      3     1       A
2      3     1       B

3      1     1       A
3      1     1       B
3      1     2       A
3      1     2       B
3      2     1       A
3      2     1       B
3      2     2       A
3      2     2       B"

【问题讨论】:

    标签: r dataframe function dplyr tidyverse


    【解决方案1】:

    这是一个替代方案(不像@Allan Cameron +1 优雅)dplyr 解决方案:

    library(dplyr)
    df %>% 
      group_by(study) %>% 
      mutate(x = n()/length(unique(sample)),
             sample =  rep(row_number(), each=x, length.out = n()),
             y = length(unique(group)),
             group = ifelse(y==1, 1, group)) %>% 
      select(-x, -y) 
    
       study sample group outcome
       <int>  <int> <dbl> <chr>  
     1     1      1     1 A      
     2     1      1     1 B      
     3     1      1     2 A      
     4     1      1     2 B      
     5     1      2     1 A      
     6     1      2     1 B      
     7     1      2     2 A      
     8     1      2     2 B      
     9     2      1     1 A      
    10     2      1     1 B      
    11     2      2     1 A      
    12     2      2     1 B      
    13     2      3     1 A      
    14     2      3     1 B      
    15     3      1     1 A      
    16     3      1     1 B      
    17     3      1     2 A      
    18     3      1     2 B      
    19     3      2     1 A      
    20     3      2     1 B      
    21     3      2     2 A      
    22     3      2     2 B 
    

    【讨论】:

      【解决方案2】:

      你可以这样做:

      library(dplyr)
      
      data %>% 
        group_by(study) %>% 
        mutate(across(tidyselect::vars_select_helpers$where(is.numeric),
                      function(x) as.numeric(as.factor(x)))) %>%
        as.data.frame()
      

      生成的数据框如下所示:

         study sample group outcome
      1      1      1     1       A
      2      1      1     1       B
      3      1      1     2       A
      4      1      1     2       B
      5      1      2     1       A
      6      1      2     1       B
      7      1      2     2       A
      8      1      2     2       B
      9      2      1     1       A
      10     2      1     1       B
      11     2      2     1       A
      12     2      2     1       B
      13     2      3     1       A
      14     2      3     1       B
      15     3      1     1       A
      16     3      1     1       B
      17     3      1     2       A
      18     3      1     2       B
      19     3      2     1       A
      20     3      2     1       B
      21     3      2     2       A
      22     3      2     2       B
      

      【讨论】:

      • @SimonHarmel 查看我的更新 - 现在这应该同时适用于数据框中的所有数字列
      • 接受和+1。但我可能需要更彻底地检查这一点。
      • Allan,如果我想保留函数中的一个或多个数值变量,而它们仍然应该是输出的一部分,你建议我怎么做?
      • @SimonHarmel across 的第一个参数允许您指定应用转换的列。在我的示例中,我们根据列是否为数字进行选择。但是,您可以通过提供名称来手动选择列,例如 mutate(across(all_of(c("sample", "group")), function(x) as.numeric(as.factor(x)))) 。有几种方法可以选择您想要的列 - 请参阅 dplyr.tidyverse.org/reference/select.html
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-27
      • 1970-01-01
      • 1970-01-01
      • 2012-01-03
      • 1970-01-01
      相关资源
      最近更新 更多