r-使用purrr一次将函数应用于两列



我有一个简化的tibble,其中我选择两列(手动(并将它们传递给自定义函数,但在本例中仅使用sum。关于如何扩展它以容纳任何数量的ko的任何想法。在这种情况下只有2个,但假设有5个?

library(dplyr)
library(purrr)
df <- tibble(l2fc_ko1 = rnorm(1:10), l2fc_ko2 = rnorm(1:10), ctrl_ko1 = rnorm(1:10), ctrl_ko2 = rnorm(1:10))
df %>% mutate(ko1_sum = map2_dbl(ctrl_ko1, l2fc_ko1, sum),
ko2_sum = map2_dbl(ctrl_ko2, l2fc_ko2, sum))

我们可以使用pivot_longer来重塑数据,为每个级别的ko创建一列。计算总和,然后pivot_wider返回到原始格式:

library(tidyverse)
df %>% 
mutate(idx = row_number()) %>% 
pivot_longer(-idx, names_sep = '_', names_to = c('group', 'ko')) %>% 
pivot_wider(names_from = group, values_from = value) %>% 
mutate(sum = l2fc + ctrl) %>% 
pivot_wider(names_from = ko, values_from = c(l2fc, ctrl, sum))
idx l2fc_ko1 l2fc_ko2 ctrl_ko1 ctrl_ko2 sum_ko1 sum_ko2
<int>    <dbl>    <dbl>    <dbl>    <dbl>   <dbl>   <dbl>
1     1  -1.04    -0.710    -0.288   -1.65   -1.33   -2.36 
2     2   0.0338   0.400    -0.850    0.319  -0.816   0.719
3     3   2.08     0.723     0.325    0.314   2.40    1.04 
4     4   0.740   -0.411    -0.307    1.77    0.433   1.36 
5     5   0.347   -1.57     -0.153    0.657   0.195  -0.915
6     6  -0.998   -0.145     0.265   -1.95   -0.733  -2.09 
7     7   2.05    -0.0876   -0.909   -0.190   1.14   -0.278
8     8   0.0735  -0.134    -2.04    -0.832  -1.96   -0.966
9     9   1.52     2.37      1.53    -0.596   3.05    1.78 
10    10   1.42    -0.753    -1.61     1.84   -0.194   1.09

如果您有一个动态数量的成对ctrl_/l2fc_列,请尝试以下操作:

  1. 确保我们有所有具有相应l2fc_ctrl_(反之亦然(:

    ctrls <- grep("^ctrl_ko", names(df), value = TRUE)
    l2fcs <- gsub("^ctrl", "l2fc", ctrls)
    ctrls <- ctrls[ l2fcs %in% names(df) ]
    l2fcs <- l2fcs[ l2fcs %in% names(df) ] # or intersect(l2fcs, names(df))
    
  2. 将这些组合成一个向量(我们稍后将对其进行拆分(,并将其转换为我们需要的新_sum名称。

    nms <- c(l2fcs, ctrls)
    nms
    # [1] "l2fc_ko1" "l2fc_ko2" "ctrl_ko1" "ctrl_ko2"
    newnms <- gsub("ctrl_(.*)", "\1_sum", ctrls)
    newnms
    # [1] "ko1_sum" "ko2_sum"
    
  3. 使用split.default(将df拆分为列组(和rowSums,我们可以设计两个_sum列:

    setNames(as.data.frame(lapply(split.default(df[nms], gsub(".*_ko", "", nms)), rowSums)), newnms)
    #       ko1_sum    ko2_sum
    # 1   1.0643199  1.7603198
    # 2  -2.3460066  2.9914827
    # 3   0.1912111 -0.3537572
    # 4   1.8475373 -0.8877151
    # 5   2.2994618  0.3716338
    # 6  -0.5365936 -1.0810583
    # 7   1.2542526 -1.0687119
    # 8  -1.8578221 -3.5073630
    # 9   2.4785211 -4.8546746
    # 10 -0.7027090  1.3562360
    
  4. 我们可以cbind/bind_cols,也可以mutate。对于后者,我们将在mutate环境中用cur_data()替换df,并且我们需要添加as.data.frame(

    从以下选项中选择一个,所有选项都能有效地产生相同的结果:

    cbind(df, setNames(lapply(split.default(df[nms], gsub(".*_ko", "", nms)), rowSums), newnms))
    bind_cols(df, setNames(lapply(split.default(df[nms], gsub(".*_ko", "", nms)), rowSums), newnms))
    df %>% 
    mutate(
    setNames(
    as.data.frame(
    lapply(split.default(cur_data()[nms], gsub(".*_ko", "", nms)), rowSums)),
    newnms)
    )
    # # A tibble: 10 x 6
    #    l2fc_ko1 l2fc_ko2 ctrl_ko1 ctrl_ko2 ko1_sum ko2_sum
    #       <dbl>    <dbl>    <dbl>    <dbl>   <dbl>   <dbl>
    #  1   1.37      1.30    -0.307   0.455    1.06    1.76 
    #  2  -0.565     2.29    -1.78    0.705   -2.35    2.99 
    #  3   0.363    -1.39    -0.172   1.04     0.191  -0.354
    #  4   0.633    -0.279    1.21   -0.609    1.85   -0.888
    #  5   0.404    -0.133    1.90    0.505    2.30    0.372
    #  6  -0.106     0.636   -0.430  -1.72    -0.537  -1.08 
    #  7   1.51     -0.284   -0.257  -0.784    1.25   -1.07 
    #  8  -0.0947   -2.66    -1.76   -0.851   -1.86   -3.51 
    #  9   2.02     -2.44     0.460  -2.41     2.48   -4.85 
    # 10  -0.0627    1.32    -0.640   0.0361  -0.703   1.36 
    

rowwise怎么样?可以使用cc_across指定所需的列。

df %>%
rowwise() %>% 
mutate(total = sum(c_across(ends_with("ko1"))))
# A tibble: 10 x 5
# Rowwise: 
l2fc_ko1 l2fc_ko2 ctrl_ko1 ctrl_ko2  total
<dbl>    <dbl>    <dbl>    <dbl>  <dbl>
1  -0.179   0.496     -1.10   -0.375  -1.27 
2  -0.0887 -0.873      0.613  -0.348   0.525
3  -2.33   -0.322     -0.515   3.03   -2.84 
4  -0.602  -0.0387     0.704  -0.118   0.102
5  -0.389  -0.00801    0.276   0.500  -0.113
6  -2.18    0.648     -0.485  -0.243  -2.66 
7   0.0529  0.237     -0.371  -0.0382 -0.318
8   0.818  -0.181      1.11   -1.25    1.93 
9  -0.271  -0.883      0.480  -0.296   0.209
10  -0.208  -1.11       1.09   -0.528   0.882

最新更新