【问题标题】:In R: dcast in function, pass column names (again!)在 R:函数中的 dcast 中,传递列名(再次!)
【发布时间】:2023-08-10 03:26:01
【问题描述】:

给定一个半长格式的 df,其中 id 变量为 ab,测量数据列在 m1m2 中。数据类型由变量v(值var1 和var2)指定。

set.seed(8)

df_l <- 
  data.frame(
    a = rep(sample(LETTERS,5),2),
    b = rep(sample(letters,5),2),
    v = c(rep("var1",5),rep("var2",5)),
    m1 = sample(1:10,10,F),
    m2 = sample(20:40,10,F)) 

看起来像:

   a b    v m1 m2
1  W r var1  3 40
2  N l var1  6 32
3  R a var1  9 28
4  F g var1  5 21
5  E u var1  4 38
6  W r var2  1 35
7  N l var2  8 33
8  R a var2 10 29
9  F g var2  7 30
10 E u var2  2 23

如果我想在 m1 中使用 id a 作为行和在 v1 作为列中的值,我会这样做:

> reshape2::dcast(df_l, a~v, value.var="m1")
  a var1 var2
1 E    4    2
2 F    5    7
3 N    6    8
4 R    9   10
5 W    3    1

我如何编写一个函数来执行此操作,将 dcast(行、列和 value.var)的参数作为参数提供,例如:

fun <- function(df,row,col,val){
  require(reshape2)
  res <-
    dcast(df, row~col, value.var=val)
  return(res)
}

我检查了 SO herehere 以尝试使用 match.calleval(substitute()) 的变体,以便“获取”函数内的参数,并尝试使用 lazyeval 包。没有成功。

我在这里做错了什么?如何让 dcast 识别变量名?

【问题讨论】:

    标签: r function casting arguments reshape2


    【解决方案1】:

    公式参数也接受字符输入。

    foo <- function(df, id, measure, val) {
        dcast(df, paste(paste(id, collapse = " + "), "~", 
                        paste(measure, collapse = " + ")), 
              value.var = val)
    }
    
    require(reshape2)
    foo(df_l, "a", "v", "m1")
    

    注意data.tabledcast (current development) 也可以直接转换多个value.var 列。所以,你也可以这样做:

    require(data.table) # v1.9.5
    foo(setDT(df_l), "a", "v", c("m1", "m2"))
    #    a m1_var1 m1_var2 m2_var1 m2_var2
    # 1: F       1       6      28      21
    # 2: H       9       2      38      29
    # 3: M       5      10      24      35
    # 4: O       8       3      23      26
    # 5: T       4       7      31      39
    

    【讨论】:

    • 两个非常好的答案 - 我会进一步研究 setDT 函数,看起来非常有用。
    • 旁白:为什么我的行不行:dcast(df, row~col, value.var=val) ?
    • 来自reshape2::dcast 的错误信息非常神秘。这是因为row ~ col 导致dcastdf 中查找名为rowcol 的列。安装dt的devel版本,加载并运行dcast(setDT(df), row ~ col, value.var="m1"),报错信息应该很清楚了。
    • 多变量选项真的好用!
    最近更新 更多