我有一个简化的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_
列,请尝试以下操作:
-
确保我们有所有具有相应
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))
-
将这些组合成一个向量(我们稍后将对其进行拆分(,并将其转换为我们需要的新
_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"
-
使用
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
-
我们可以
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
怎么样?可以使用c
或c_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