简体   繁体   English

使用r中dplyr的mutate_all()将df中的每一列除以其他列

[英]Divide each column in a df by each other column using mutate_all() from dplyr in r

I am trying to divide each column in a dataframe by each other column. 我正在尝试将数据帧中的每一列彼此分开。 Starting with a dataframe with columns A,B,C. 从具有A,B,C列的数据帧开始。 I would like to end with a dataframe with columns B/A,C/A,A/B,C/B,A/C, and B/C. 我想以包含B / A,C / A,A / B,C / B,A / C和B / C的数据框结尾。 I have found a way to do this which requires me to write a function for each denominator, but I would prefer it if I could do so by defining a single function. 我找到了一种方法来执行此操作,该方法要求我为每个分母编写一个函数,但是如果可以通过定义单个函数来实现,则希望使用该方法。

I have found a similar, but not identical question answered here. 我发现这里回答了一个类似但不完全相同的问题。 Dividing each column by the column before it in R 将每列除以R中的前一列

If possible I would like to use dplyr to solve this. 如果可能,我想使用dplyr解决此问题。

Here is the closest I have got. 这是我最近的。

## create example data frame

df <- data.frame(A=rnorm(10),
                 B=rnorm(10),
                 C=rnorm(10),)

## calculate ratios

ratio_df <- df%>%
     mutate_all(.funs = funs(A=./A,
                             B=./B,
                             C=./C))

This will return the desired results with columns A/A,B/A,C/A,A/B,B/B,C/B,A/C,B/C,C/C. 这将使用A / A,B / A,C / A,A / B,B / B,C / B,A / C,B / C,C / C返回期望的结果。 I can easily filter out A/A,B/B, and C/C giving the desired result, but it is clunky when there are a large number of columns. 我可以轻松过滤掉A / A,B / B和C / C以获得所需的结果,但是当列数很大时,它很笨拙。

Is there a way to accomplish this without writing each individual function? 有没有一种方法可以实现而无需编写每个单独的函数?

Here's an answer using purrr . 这是使用purrr的答案。

library(purrr)
library(dplyr)

df <- data.frame(A=rnorm(10),
                 B=rnorm(10),
                 C=rnorm(10))

df %>% map(~ . / df) %>% bind_cols()

What about: 关于什么:

do.call(cbind, lapply(df, function(x) x / df))

Output: 输出:

   A.A         A.B        A.C         B.A B.B        B.C        C.A        C.B C.C
1    1  0.38056317  0.4701251   2.6276847   1  1.2353406  2.1270933  0.8094934   1
2    1 -1.07851585 -1.0793270  -0.9272001   1  1.0007521 -0.9265032  0.9992484   1
3    1 -2.44512434 -4.7467554  -0.4089772   1  1.9413145 -0.2106702  0.5151149   1
4    1 -1.41765991 -2.3908820  -0.7053878   1  1.6864990 -0.4182557  0.5929443   1
5    1 -0.10640354  0.2382367  -9.3981837   1 -2.2389920  4.1975066 -0.4466296   1
6    1  2.32474492  0.3879095   0.4301547   1  0.1668611  2.5779212  5.9930092   1
7    1  0.95122898  1.6102188   1.0512716   1  1.6927773  0.6210336  0.5907452   1
8    1 -0.15996970 -0.1422422  -6.2511840   1  0.8891823 -7.0302611  1.1246287   1
9    1 -0.04431519  0.2121086 -22.5656275   1 -4.7863640  4.7145657 -0.2089269   1
10   1  0.26662240 -0.3524232   3.7506226   1 -1.3218065 -2.8374974 -0.7565404   1

Another answe using purrr which will also have the columns named as you specified: 另一个使用purrr答案将具有您指定的命名列:

library(tidyverse)

df %>% 
  select_if(is.numeric) %>% 
  map(~./df %>% select_if(is.numeric)) %>% 
  imap(~set_names(.x, paste0(names(.x), "_", .y))) %>% 
  bind_cols()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM