R:使用dplyr对多个列进行变异
关于堆栈溢出,有各种各样的问题,但我一直无法找到我的问题的解决方案,如下所示 假设我有一个数据帧(或TIBLE)R:使用dplyr对多个列进行变异,r,dplyr,mutate,R,Dplyr,Mutate,关于堆栈溢出,有各种各样的问题,但我一直无法找到我的问题的解决方案,如下所示 假设我有一个数据帧(或TIBLE)df,有两列,比如说X1和X2。我有一个函数,比如说f,它接受输入X1和X2并输出一个向量,比如说[V1,V2]。 现在,如果输出是一个单例,那么我就可以写了 df %>% mutate(V = f(X1,X2)) 要将标有V的列添加到mydf,条目将是f(X1,X2)。但是,我想添加两列,V1和V2。我不知道怎么做 当然,我可以这样做 df %>% mutate(V1
df
,有两列,比如说X1
和X2
。我有一个函数,比如说f
,它接受输入X1
和X2
并输出一个向量,比如说[V1,V2]
。
现在,如果输出是一个单例,那么我就可以写了
df %>% mutate(V = f(X1,X2))
要将标有V
的列添加到mydf
,条目将是f(X1,X2)
。但是,我想添加两列,V1
和V2
。我不知道怎么做
当然,我可以这样做
df %>% mutate(V1 = f(X1,X2)[1], V2 = f(X1,X2)[2]),
但这(我假设)涉及调用函数f
两次;我有一个很大的数据集,所以我不想叫它两次。
或者,我也可以这样做
df %>% mutate(V_list = as.list(f(X1,X2)), V1 = V_list[[1]], V2 = V_list[[2]]) %>% select(-V_list),
但这似乎是一个相当笨拙的方式,我宁愿不要
此外,我希望最终将此应用于组
ed tible,因此编写此文件的简单方法将为组中的每个条目复制V_列表
。因此,理想情况下,任何答案都是“矢量化”的,如下所示。
假设我已经完成了df%>%groupby(var1)
,并且有一个函数f
,该函数将具有两列的数据帧作为其输入,这应该被认为是“成对向量”,然后输出具有两列的新数据帧
下面是一些设置示例的代码
library(dplyr)
df = tibble(var1 = c(1,1,2,2), X1 = c(1,2,3,4), X2 = c(5,6,7,8))
f = function(sub_df, var){ return( data.frame(x1 = (x1+x2)^var, x2 = (x1-x2)^var) ) }
这可能不是一个理想的解决方案,但我已经面临这种情况,这是我通常做的。从函数中返回分隔符分隔的字符串,并基于该分隔符分隔列
f = function(x1,x2){ return( toString(c(x1+x2, x1-x2))) }
library(tidyverse)
df %>%
mutate(new = map2_chr(X1, X2, f)) %>%
separate(new, c("col1", "col2"), sep = ",", convert = TRUE)
# A tibble: 2 x 4
# X1 X2 col1 col2
# <dbl> <dbl> <int> <int>
#1 1 3 4 -2
#2 2 4 6 -2
f=function(x1,x2){return(toString(c(x1+x2,x1-x2)))}
图书馆(tidyverse)
df%>%
突变(新的=map2_-chr(X1,X2,f))%>%
单独(新,c(“col1”、“col2”)、sep=“,”、convert=TRUE)
#一个tibble:2x4
#X1 X2 col1 col2
#
#1 1 3 4 -2
#2 2 4 6 -2
这可能不是一个理想的解决方案,但我遇到过这种情况,这是我通常做的事情。从函数中返回分隔符分隔的字符串,并基于该分隔符分隔列
f = function(x1,x2){ return( toString(c(x1+x2, x1-x2))) }
library(tidyverse)
df %>%
mutate(new = map2_chr(X1, X2, f)) %>%
separate(new, c("col1", "col2"), sep = ",", convert = TRUE)
# A tibble: 2 x 4
# X1 X2 col1 col2
# <dbl> <dbl> <int> <int>
#1 1 3 4 -2
#2 2 4 6 -2
f=function(x1,x2){return(toString(c(x1+x2,x1-x2)))}
图书馆(tidyverse)
df%>%
突变(新的=map2_-chr(X1,X2,f))%>%
单独(新,c(“col1”、“col2”)、sep=“,”、convert=TRUE)
#一个tibble:2x4
#X1 X2 col1 col2
#
#1 1 3 4 -2
#2 2 4 6 -2
使用tidyr 1.0.0,您可以使用更广泛的
修改函数以命名输出
f = function(x1,x2) c(a = x1 + x2, b = x1 - x2)
创建一个新列,该列是一个包含每行向量的列表,然后将unnest\u wider
应用于该列以将向量元素拆分为各自的列
df %>%
mutate(new = map2(X1, X2, f)) %>%
unnest_wider(new)
# # A tibble: 4 x 5
# var1 X1 X2 a b
# <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 1 1 5 6 -4
# 2 1 2 6 8 -4
# 3 2 3 7 10 -4
# 4 2 4 8 12 -4
df%>%
突变(新的=map2(X1,X2,f))%>%
unnest_加宽(新)
##A tibble:4 x 5
#var1 X1 X2 a b
#
# 1 1 1 5 6 -4
# 2 1 2 6 8 -4
# 3 2 3 7 10 -4
# 4 2 4 8 12 -4
使用tidyr 1.0.0,您可以使用更广泛的
修改函数以命名输出
f = function(x1,x2) c(a = x1 + x2, b = x1 - x2)
创建一个新列,该列是一个包含每行向量的列表,然后将unnest\u wider
应用于该列以将向量元素拆分为各自的列
df %>%
mutate(new = map2(X1, X2, f)) %>%
unnest_wider(new)
# # A tibble: 4 x 5
# var1 X1 X2 a b
# <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 1 1 5 6 -4
# 2 1 2 6 8 -4
# 3 2 3 7 10 -4
# 4 2 4 8 12 -4
df%>%
突变(新的=map2(X1,X2,f))%>%
unnest_加宽(新)
##A tibble:4 x 5
#var1 X1 X2 a b
#
# 1 1 1 5 6 -4
# 2 1 2 6 8 -4
# 3 2 3 7 10 -4
# 4 2 4 8 12 -4
这有点令人不满意,但如果我找不到更好的方法,它确实看起来应该有效,谢谢+1--我不确定如何将其矢量化,以使其适用于小组……这有点不令人满意,但如果我找不到更好的方法,它确实看起来应该有效,谢谢+1--我不确定如何将其矢量化,以使其适用于小组……这对小组有效吗?例如,代替上面的函数f
,我可能想groupby(var1)
然后将lm
拟合到X1
和X2
的数据中(比如X1~X2
);从这里,我想增加两个系数。这意味着我将得到一个包含两行三列的数据帧:var1
、coeff1
和coeff2
是。unnest_wider只是将列表列拆分为单独的列,如果列表列是在分组后创建的,或者如果列表列是使用Summary而不是mutate创建的(正如您为每个组提供的lm示例中所示),则其工作原理是相同的,这与列表列的创建方式无关。这是否适用于组?例如,代替上面的函数f
,我可能想groupby(var1)
然后将lm
拟合到X1
和X2
的数据中(比如X1~X2
);从这里,我想增加两个系数。这意味着我将得到一个包含两行三列的数据帧:var1
、coeff1
和coeff2
是。unnest_wider只是将列表列拆分为单独的列,如果列表列是在分组后创建的,或者如果它是使用摘要而不是变异创建的(就像您为每个组提供lm的示例中那样),则其工作原理相同,与列表列的创建方式无关。