【问题标题】:R: programmatic alternative for tidyr::spread?R:tidyr::spread 的编程替代方案?
【发布时间】:2017-08-22 10:03:37
【问题描述】:

我有 R data.frames 有不同数量的列。最后一列是数字,其余的是字符串。我需要安排它们,以便传播最后一个非数字列。困难在于我想以编程方式执行此操作,因为我不知道列名。

例如

df <- data.frame(varA = c("A1", "A1", "A2", "A2"),
                 varB = c("B1", "B2", "B1", "B2"),
                 val = c(1, 2, 3, 4))

我到达我想要的地方

tidyr::spread(df, varB, val)

但是当传播变量的名称未知时,我不知道如何实现这一点。

例如这行不通:

tidyr::spread(df, names(df)[ncol(df) - 1], val)

我已经尝试过tidyverse 解决方案,但基本 R 对我来说同样适用。

【问题讨论】:

    标签: r dataframe tidyr


    【解决方案1】:

    spread_tidyr 0.7.0 开始已弃用,tidyr 中的编程已切换到 tidy 评估。有关更多背景信息,请参阅this article

    要在spread 中使用字符串,您需要rlang 包中的sym 函数以及!! 来取消引用以进行评估。

    spread(df, !!rlang::sym(names(df)[ncol(df) - 1]), val)
    
      varA B1 B2
    1   A1  1  2
    2   A2  3  4
    

    【讨论】:

      【解决方案2】:

      我们可以使用spread_

      tidyr::spread_(df, names(df)[ncol(df) - 1], "val")
      #    varA B1 B2
      #1   A1  1  2
      #2   A2  3  4
      

      【讨论】:

      • 谢谢!正是我需要的。奇怪的是,这不适用于 ifelse 语句,例如:df2 &lt;- ifelse(ncol(df) == 2, df[,ncol(df)], tidyr::spread_(...))。幸运的是if() ... else() 结构运行良好。
      • @Antti 不清楚条件,但您可以在spread 内尝试,即tidyr::spread_(df, ifelse(ncol(df)==2, names(df)[ncol(df)-1], names(df)[1]), "val")
      • @Antti ifelse“返回一个与test具有相同形状的值”(来自?ifelse)。如果您的测试是一个包含一个元素的向量,例如ncol(df) == 2,那么ifelse 将返回一个包含一个元素的向量,而不是一个数据框。使用if{} else{},因为您发现使用它返回单个值,如 akrun 的评论中所示。
      • 感谢 akrun 和 Gregor 的 cmets!现在说得通了。
      猜你喜欢
      • 2011-03-28
      • 2011-09-19
      • 1970-01-01
      • 2015-03-05
      • 1970-01-01
      • 2011-12-24
      • 2021-04-08
      • 2023-03-23
      • 1970-01-01
      相关资源
      最近更新 更多