在调用时使用dplyr mutate_中的多列函数
我想使用dplyr的在调用时使用dplyr mutate_中的多列函数,r,dplyr,R,Dplyr,我想使用dplyr的mutate_at函数将一个函数应用于数据帧中的多个列,其中该函数输入它直接应用到的列以及数据帧中的另一列 作为一个具体的例子,我希望对以下数据帧进行变异 # Example input dataframe df <- data.frame( x = c(TRUE, TRUE, FALSE), y = c("Hello", "Hola", "Ciao"), z = c("World", "ao", "HaOlam") ) 返回如下所示的数据帧
mutate_at
函数将一个函数应用于数据帧中的多个列,其中该函数输入它直接应用到的列以及数据帧中的另一列
作为一个具体的例子,我希望对以下数据帧进行变异
# Example input dataframe
df <- data.frame(
x = c(TRUE, TRUE, FALSE),
y = c("Hello", "Hola", "Ciao"),
z = c("World", "ao", "HaOlam")
)
返回如下所示的数据帧
# Desired output dataframe
df2 <- data.frame(x = c(TRUE, TRUE, FALSE),
y_1 = c("Hello", "Hola", NA),
z_1 = c("World", "ao", NA))
我知道这可以在BaseR中以多种方式实现,但为了可读性、与数据库接口等原因,我特别希望使用dplyr的mutate_at
函数来实现这一目标
下面是关于stackoverflow的一些类似问题,这些问题没有解决我在这里提出的问题:
在@eipi10对这个问题的评论中,@eipi10回答了这个问题,但我写在这里是为了子孙后代 这里的解决方案是使用:
df %>%
mutate_at(.vars = vars(y, z),
.funs = list(~ ifelse(x, ., NA)))
您还可以将新的cross()
函数与mutate()
一起使用,如下所示:
df %>%
mutate(across(c(y, z), ~ ifelse(x, ., NA)))
temp_fn <- function(input) ifelse(test = df[["x"]],
yes = input,
no = NA)
df %>%
mutate_at(.vars = vars(y, z),
.funs = temp_fn)
在这里使用公式运算符(如~ifelse(…)
)表示ifelse(x,,,NA)
是一个匿名函数,它是在调用mutate_at()时定义的
这类似于在调用mutate_at()
之外定义函数,如下所示:
df %>%
mutate(across(c(y, z), ~ ifelse(x, ., NA)))
temp_fn <- function(input) ifelse(test = df[["x"]],
yes = input,
no = NA)
df %>%
mutate_at(.vars = vars(y, z),
.funs = temp_fn)
temp\u fn%
在(.vars=vars(y,z)处突变_,
.funs=温度(fn)
请注意dplyr中的语法更改:在dplyr版本0.8.0之前,您只需编写.funs=funs(ifelse(x,,,NA))
,但funs()
函数已被弃用,并将很快从dplyr中删除。补充先前的响应,如果您希望mutate_at()
添加新变量(而不是替换),如原始问题中的名称,如z_1
和y_1
,您只需:
- dplyr>=1带
cross()
:添加.names=“{.col}\u 1”
,或者使用列表('1'=~ifelse(x,,,NA)
(反勾!)
- dplyr[0.8,1[:使用
list('1'=~ifelse(x,,,NA)
- dplyr%
突变(跨越(c(y,z),
列表(~ifelse(x,NA)),
.names=“{.col}_1”))
#>x y z y_1 z_1
#>1真正的你好世界你好世界
#>2真的好啊好啊好啊
#>3假乔浩林
## 0.8 - %
在(.vars=vars(y,z)处突变_,
.funs=list(`1`=~ifelse(x,,,NA)))
#>x y z y_1 z_1
#>1真正的你好世界你好世界
#>2真的好啊好啊好啊
#>3假乔浩林
##0.8之前
df%>%
在(.vars=vars(y,z)处突变_,
.funs=funs(`1`=ifelse(x,NA)))
#>警告:`funs()`从dplyr 0.8.0开始就不推荐使用。
#>请使用函数或lambda的列表:
#>
#>#简单命名列表:
#>列表(平均值=平均值,中位数=中位数)
#>
#>#使用'tibble::lst()'自动命名:
#>tibble::lst(平均值、中值)
#>
#>#使用lambdas
#>列表(~平均值(,修剪=0.2),~中值(,na.rm=TRUE))
#>此警告每8小时显示一次。
#>调用`lifecycle::last_warnings()`查看此警告的生成位置。
#>x y z y_1 z_1
#>1真正的你好世界你好世界
#>2真的好啊好啊好啊
#>3假乔浩林
由(v0.3.0)于2020年10月3日创建
有关更多详细信息和技巧,请参阅:
df%>%mutate_at(vars(y,z),funs(ifelse(x,NA))
@eipi10啊,好的。因此,如果我在调用funs()时实际包装了ifelse(x,NA)
,上述代码就可以工作了
。谢谢!我已经检查了你的解决方案,效果非常好。你的解决方案正是我想要的!“这里使用funs()表示ifelse(x,,,NA)是一个匿名函数”——funs()
与传统的匿名函数,函数(x)有何不同
?根据我的经验,最值得注意的是,它需要更少的键入,并且可读性类似。但是,它还允许您提供匿名函数列表(例如funs(avg=mean(.),total=sum(.,na.rm=TRUE))
。请参阅。