每行都有dplyr自定义函数

时间:2016-03-05 08:46:51

标签: r dplyr

我开始使用dplyr,我想在plyr中投放旧dplyr程序 我有一个包含此列的数据框:

model,label, value0,value1,value2..... , value100

我想使用dplyr来添加一个新列rms,它将值0调用到值100作为此函数的输入参数rms

rms <- function(value){
    rms = sqrt(sum( value^2))/sqrt(length(value))
    return (rms)
}

如何在mutate中调用输入参数。

table %>%
  rowwise() %>%
  mutate(rms= rms( ???)

提前感谢

3 个答案:

答案 0 :(得分:0)

一种选择可能是首先使用来自tidyr的gather将数据转换为长格式。这将允许您将函数应用于单个列。一个简单的例子

library(dplyr)
library(tidyr)

df <- data.frame(model = c("Model1", "Model2", "Model3"),
                 label = c("Label1", "Label2", "Label3"),
                 value0 = c(1, 2, 3),
                 value1 = c(4, 5, 6),
                 value2 = c(7, 8, 9), 
                 stringsAsFactors = FALSE)

long_df <- df %>%
    gather(value_name, value, -model, -label)

model  label value_name value
1 Model1 Label1     value0     1
2 Model2 Label2     value0     2
3 Model3 Label3     value0     3
4 Model1 Label1     value1     4
5 Model2 Label2     value1     5
6 Model3 Label3     value1     6
7 Model1 Label1     value2     7
8 Model2 Label2     value2     8
9 Model3 Label3     value2     9

现在,您可以应用函数为每组模型和标签创建rms值。

rms <- function(value){
  rms = sqrt(sum(value^2))/sqrt(length(value)) 
  return(rms) 
}

rms_df <- long_df %>%
  group_by(model, label) %>%
  summarise(rms = rms(value))

您现在加入rms_df回原来的df和bingo,你有一个rms列。

df <- df %>%
  left_join(rms_df)

   model  label value0 value1 value2      rms 
 1 Model1 Label1      1      4      7 4.690416
 2 Model2 Label2      2      5      8 5.567764
 3 Model3 Label3      3      6      9 6.480741

不使用rowwise,也许会有人来解释如何这样做,但希望这很有用。

答案 1 :(得分:0)

感谢您的建议。 谦虚地,我想到了这个解决方案,但通过重塑包装。

我确信dplyr有一个解决方案 如果我这样做:

table %>%
  rowwise() %>%
  mutate(rms= rms( c(Frame0,Frame2))

我可以在frame0和第2帧上运行我的功能。但是如果我使用c(&#34; Frame0&#34;,&#34; frame2&#34;)那就失败了。

我想要一个完整的dplyr解决方案。 欢呼声

答案 2 :(得分:0)

好吧,我不确定Frame0和Frame2是什么,但是这里有一个稍微改变的方法来绕过连接的东西。再次使用我的制作df。

df <- data.frame(model = c("Model1", "Model2", "Model3"),
                 label = c("Label1", "Label2", "Label3"),
                 value0 = c(1, 2, 3),
                 value1 = c(4, 5, 6),
                 value2 = c(7, 8, 9), 
                 stringsAsFactors = FALSE)

我们使用tidyr::gather将df转换为长格式,然后将您的函数应用于单列,然后使用tidyr::spread将其转换回宽格式。 Tidyr和dplyr打算一起工作,所以我认为你不会从“完整的dplyr解决方案”中获得太多收益。

rms_df <- df %>%
  gather(value_name, value, -model, -label) %>%
  group_by(model, label) %>%
  mutate(rms = rms(value)) %>%
  spread(value_name, value)

> rms_df
Source: local data frame [3 x 6]
   model  label      rms value0 value1 value2
  (chr)  (chr)    (dbl)  (dbl)  (dbl)  (dbl)
1 Model1 Label1 4.690416      1      4      7
2 Model2 Label2 5.567764      2      5      8
3 Model3 Label3 6.480741      3      6      9