当前位置: 首页 > 知识库问答 >
问题:

如何在dplyr中创建突变调用的动态编号和名称?

滕鸿畴
2023-03-14

我正在创建一个动态排列函数来创建与顺序无关的参数。在函数之外,我已经能够使用dplyr对这种方法进行硬编码。但是,我想对其进行泛化,以便我可以使用相同的函数来排列3个因子或6个因子,而无需输入所有重复调用。但是,我还没有弄清楚如何使其工作。

以下是 3 个变量的所有排列的简单数据框 df

#> dput(df)
structure(list(var1 = structure(c(1L, 1L, 2L, 2L, 3L, 3L), .Label = c("a", 
"b", "c"), class = "factor"), var2 = structure(c(2L, 3L, 1L, 
3L, 1L, 2L), .Label = c("a", "b", "c"), class = "factor"), var3 =     structure(c(3L, 
2L, 3L, 1L, 2L, 1L), .Label = c("a", "b", "c"), class = "factor"), 
    X1 = c(0.5, 0.5, 0.8, 0.8, 0.3, 0.3), X2 = c(0.8, 0.3, 0.5, 
    0.3, 0.5, 0.8), X3 = c(0.3, 0.8, 0.3, 0.5, 0.8, 0.5)), .Names = c("var1", 
"var2", "var3", "X1", "X2", "X3"), row.names = c(NA, -6L), class = "data.frame")

我的目标是得到每个变量的平均顺序独立值。为了达到这个目标,我需要创建两个中间变量:一个是乘法m1, m2, m3, m4,一个是减法s1, s2, s3, s4。变量m1s1是特殊的,m1=X1s1=X1-1。但是,其他的需要参考之前的:m2=X2*X1s2=m2-m1

我试图将这个问题的思想结合起来:R-dplyr-mutate-使用动态变量名和lazyeval interp,这样我就可以动态地引用其他变量,也可以动态地命名变异列。然而,它只保留了最后一个发送的,并且重命名不起作用,因此我得到了一个单独的附加列,例如,X2*X3,这在本例中是3。当我有5时,它给出了一个附加列X4*X5

for(n in 2:n_params) {
     varname <- paste("m", n, sep=".")
     df <- mutate_(df, .dots = setNames(interp(~one*two, one=as.name(paste0("X",n-1)),
                                               two=as.name(paste0("X",n))),varname))
     df
   }

由于我无法理解为什么这不起作用,所以我设置了一系列if语句来计算ms和ss。

 xx <- data.frame(df) %>%
     mutate(m1 = X1,
            s1 = X1 - 1)
   if(n_params >= 2) {
     xx <- data.frame(xx) %>%
       mutate(m2 = m1 * X2,
              s2 = m2 - m1)
   }
   if(n_params >= 3) {
     xx <- data.frame(xx) %>%
       mutate(m3 = m2 * X3,
              s3 = m3 - m2)
   }
   if(n_params >= 4) {
     xx <- data.frame(xx) %>%
       mutate(m4 = m3 * X4,
              s4 = m4 - m3)
   }
   if(n_params >= 5) {
     xx <- data.frame(xx) %>%
       mutate(m5 = m4 * X5,
         s5 = m5 - m4)
   }
   if(n_params >= 6) {
     xx <- data.frame(xx) %>%
       mutate(m6 = m5 * X6,
              s6 = m6 - m5)
   }

似乎我应该能够编写一个创建此函数的函数

在伪代码中:

function(n_params) {
 function(x) {
   new_df <- df %>% 
            mutate(m1 = X1,
                  s1 = X1 - 1)
   for(i in 2:n_params){
    new_df <- append(call to new_df, 
             mutate(mi = Xi*Xi-1,
                   si = mi-mi-1)
     }
   }
}

但是,我不知道如何将< code > lazy val interp 和setNames结合起来,以允许引用前面的变异值。

我可以把它留在if函数中,但如果可能的话,我很乐意让它更紧凑。

感兴趣的最终最终输出是每个初始变量的所有排列上的平均s值。我是在一个单独的函数中完成的。

共有1个答案

顾跃
2023-03-14

不是最漂亮的东西,但它是有效的:

n_params = 3

xx1 = df %>%
mutate(m1 = X1,
       s1 = X1 - 1)

for (i in 2:n_params) {
xx1 = xx1 %>%
    mutate_(.dots = setNames(list(varval = paste0("m", i - 1, " * X", i)),
                             paste0("m", i))) %>%
    mutate_(.dots = setNames(list(varval = paste0("m", i, " - m", i - 1)),
                             paste0("s", i)))
}

使用<code>lazyeval<code>可能有更好的方法。希望其他人会给出一个很好的答案,但这确实与您的问题中产生的<code>xx</code>相匹配(对于<code>n_params=3):

identical(xx, xx1)
# [1] TRUE
 类似资料:
  • 我想使用在数据帧中创建多个新列。列名及其内容应动态生成。 来自IRIS的示例数据: 我创建了一个函数来从变量中更改新列:

  • 我想使用<code>dplyr::mutate()</code>在数据帧中创建多个新列。应动态生成列名及其内容。 来自iris的示例数据: 我创建了一个函数,可以从<code>Petal中修改我的新列。宽度变量: 现在我创建一个循环来构建我的列: 然而,由于mutate认为varname是一个文字变量名,因此循环只创建一个新变量(称为varname),而不是四个(称为petal.2-petal.5

  • 问题内容: 我正在使用ajax google maps脚本,需要在for循环中创建动态变量名称。 我想的是:,,等。我想这有什么问题 Firebug给了我这个: 问题答案: 为此使用数组。

  • 我正在用android创建一款纸牌游戏(21点)。前两张卡是easy card1和card2,但是我想按一下“点击我”按钮,发一张新卡,并将其分配给card3、card4等。有没有任何方法可以做到这一点,而无需创建所需的最大变量数,并使用if-then语句检查它们是否被分配了值?

  • 我正在将java脚本移动到dart,在java脚本中我创建了动态变量,例如 我怎么能用飞镖呢?

  • 本文向大家介绍如何在JavaScript循环内创建动态变量名?,包括了如何在JavaScript循环内创建动态变量名?的使用技巧和注意事项,需要的朋友参考一下 为此,您需要向当前范围添加属性。使用它来实现此目的,这适用于程序中的当前作用域- 上面将获得您想要的内容,并像下面这样检索它- 如上所示,它将为您提供文本“在此处添加”。