【问题标题】:Replacing value depending on paired column根据配对列替换值
【发布时间】:2020-06-28 00:09:32
【问题描述】:

我有一个数据框,每个样本有两列(n > 1000 个样本):

df <- data.frame(
    "sample1.a" = 1:5, "sample1.b" = 2,
    "sample2.a" = 2:6, "sample2.b" = c(1, 3, 3, 3, 3),
    "sample3.a" = 3:7, "sample3.b" = 2)

如果.b列为零,则.a列对应的值应设置为NA。

我想在 colnames(不带后缀)上编写一个函数来过滤每对列和条件交换值。有没有基于 tidyverse 的更简单的方法?

【问题讨论】:

    标签: r tidyverse pairwise


    【解决方案1】:

    我们可以将 data.frame 拆分成一个 data.frames 列表并在base R中进行替换

    df1 <- do.call(cbind, lapply(split.default(df,  
       sub("\\..*", "", names(df))), function(x) {
                 x[,1][x[2] == 0] <- NA
          x}))
    

    或者另一个选项是Map

    acols <- endsWith(names(df), "a")
    bcols <- endsWith(names(df), "b")
    df[acols] <- Map(function(x, y) replace(x, y == 0, NA), df[acols], df[bcols])
    

    或者如果列与'a'、'b'列交替,使用逻辑索引进行回收,用'b'列创建逻辑矩阵并将'a'列中的对应值赋给NA

    df[c(TRUE, FALSE)][df[c(FALSE, TRUE)] == 0] <- NA
    

    tidyverse 的选项,通过重塑为“长”格式(pivot_longer),如果“a”中有相应的 0,则将“a”列更改为 NA,然后重新整形为“宽” ' 格式为pivot_wider

    library(dplyr)
    library(tidyr)
    df %>%
        mutate(rn = row_number()) %>%
       pivot_longer(cols = -rn, names_sep="\\.",
            names_to = c('group', '.value')) %>% 
       mutate(a = na_if(b, a == 0)) %>%
       pivot_wider(names_from = group, values_from = c(a, b)) %>% 
       select(-rn)
    # A tibble: 5 x 6
    #  a_sample1 a_sample2 a_sample3 b_sample1 b_sample2 b_sample3
    #      <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl>
    #1         2         1         2         2         1         2
    #2         2         3         2         2         3         2
    #3         2         3         2         2         3         2
    #4         2         3         2         2         3         2
    #5         2         3         2         2         3         2
    

    【讨论】:

    • 我认为在你的 tidyverse 版本中mutate(a = na_if(b, b &lt; 2) 应该是正确的。
    猜你喜欢
    • 2016-11-22
    • 2017-03-04
    • 2021-05-14
    • 1970-01-01
    • 2021-09-23
    • 2021-06-08
    • 2021-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多