使用 mutate_all 将所有列除以选定的列 [英] Divide all columns by a chosen column using mutate_all

查看:15
本文介绍了使用 mutate_all 将所有列除以选定的列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像这样的示例数据框(我的完整数据框有d"加上 57 个元素):

I have a sample data frame that looks like this (my full dataframe has "d" plus 57 elements):

d <- seq(0, 100, 0.5) 
Fe <- runif(201, min = 0, max = 1000) 
Ca <- runif(201, min = 0, max = 1000) 
Zr <- runif(201, min = 0, max = 1000) 
Ti <- runif(201, min = 0, max = 1000) 
Al <- runif(201, min = 0, max = 1000) 
example <- data.frame(d, Fe, Ca, Zr, Ti, Al)
Ratio_Elements <- c("Fe", "Ti", "Zr", "d") #this subset of the 
dataframe is user defined
Detrital_Divisor <- "Zr"

Detrital_Divisor 可以根据用户输入进行更改,但始终是示例"数据框中的一列.我想将所有剩余的列除以 Detrital_Divisor 列,最好使用管道.现在我有:

The Detrital_Divisor can change based on the user input but will always be a column in the "example" dataframe. I would like to divide all the remaining columns by the Detrital_Divisor column, preferably using a pipe. Right now I have:

Example_Ratio <- example %>%
select (Ratio_Elements) #to subset to the user selected elements
mutate_all(./Detrital_Divisor)

但我收到错误:

Error in Ops.data.frame(., Detrital_Divisor) : 
  ‘/’ only defined for equally-sized data frames.

我也试过:

Example_Ratio <- example %>%
select (Ratio_Elements)
sweep(., Detrital_Divisor, MARGIN = 1, '/')

基于在此论坛上提出的类似问题,但我无法使其正常工作.我收到错误

based on similar questions that have been asked on this forum but I just can't get it to work. I get the error

    `Error in Ops.data.frame(x, aperm(array(STATS, dims[perm]), order(perm)),  : 
  list of length 206340 not meaningful.`

我知道这个问题有点重复,但我发现的其他答案在我的情况下不起作用.我的整个数据框有 57 个元素,因此编写单独划分每一列的代码会很长.

I know this question is somewhat repetitive but the other answers I have found are not working in my situation. My entire data frame has 57 elements so writing code to divide each column individually would be very long.

提前感谢您的建议.

推荐答案

可能是这样的:

library(tidyverse)

d <- seq(0, 100, 0.5) 
Fe <- runif(201, min = 0, max = 1000) 
Ca <- runif(201, min = 0, max = 1000) 
Zr <- runif(201, min = 0, max = 1000) 
Ti <- runif(201, min = 0, max = 1000) 
Al <- runif(201, min = 0, max = 1000) 
example <- data.frame(d, Fe, Ca, Zr, Ti, Al)
Ratio_Elements <- c("Fe", "Ti", "Zr", "d") #this subset of the 

Example_Ratio <- example %>%
  mutate_at(vars(-Zr), funs(. / Zr)) %>%
  select(Ratio_Elements)

我知道你说你想看到一个 mutate_all 解决方案,但我猜你不想把 Zr 分开?

I know you said you'd like to see a mutate_all solution, but I guess you don't want to divide Zr by itself?

在这种情况下mutate_at更有帮助,否则你可以做mutate_all(funs(./Zr)).

In this case mutate_at is more helpful, otherwise you can do mutate_all(funs(. / Zr)).

如果你想保留提到的向量:

If you want to keep the mentioned vector:

Detrital_Divisor <- as.symbol("Zr")

Example_Ratio <- example %>%
  mutate_at(vars(- !! Detrital_Divisor), funs(. / !! Detrital_Divisor)) %>%
  select(Ratio_Elements)


更新(dplyr 0.8.0)

既然 funsdplyr 0.8.0 开始被弃用,你可以只使用 ~,例如:

Now that funs is deprecated as of dplyr 0.8.0, you can just use ~, e.g.:

Detrital_Divisor <- as.symbol("Zr")

Example_Ratio <- example %>%
  mutate_at(vars(- !! Detrital_Divisor), ~ . / !! Detrital_Divisor) %>%
  select(Ratio_Elements)

另一方面,还有 list - 可用于以多种方式变异或命名输出,例如:

On the other hand there's also list - useful for mutating in multiple ways or naming the output, e.g.:

Example_Ratio <- example %>%
  mutate_at(vars(- !! Detrital_Divisor), list(appended_name = ~ . / !! Detrital_Divisor))


更新(dplyr 1.0.0)

dplyr 1.0.0 开始,您可能希望使用 across:

As of dplyr 1.0.0, you would probably want to use across:

Example_Ratio <- example %>%
  mutate(across(-Detrital_Divisor, ~ . / !! Detrital_Divisor)) %>%
  select(all_of(Ratio_Elements))

这篇关于使用 mutate_all 将所有列除以选定的列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆