【问题标题】:Creating several new columns in a data frame using the same function使用相同的函数在数据框中创建多个新列
【发布时间】:2019-10-30 12:04:43
【问题描述】:

对于这个基本问题,我很抱歉。我只是在努力解决应该很简单的事情。假设我有最初具有三个字段的数据框“Test”:Col1、Col2、Col3。

我想根据每个原始列创建新列。新列的每一行中的值将指定原始列上匹配行中的相应值是高于还是低于初始列的中位数。因此,例如,在所附图像中,Col4 基于 Col1。 Col5 基于 Col2。 Col6 基于 Col3。

测试数据框示例:

在单列上执行此功能并输出单列非常容易:

Test <- Test %>% mutate(Col4 = derivedFactor(

"below"= Col1 > median(Test$Col1),

"at"= Col1 == median(Test$Col1),

"above"= Col1 < median(Test$Col1)

.default = NA)

)

但是,如果我在 50 列上执行相同的操作,那么写出/复制粘贴和编辑代码可能会很乏味且效率低下。我应该提到我希望将新列添加到数据框中,而不是创建另一个数据框。此外,数据框中还有大约 200 个其他字段不会对它们执行此功能(所以我不能只使用 mutate_all)。并且列的名称不统一(我上面的示例只是示例,而不是实际的数据集),因此我无法找到 mutate_at 的模式。也许有一种方法可以手动将列名列表传递给 mutate 命令?

必须有一种简单而优雅的方式来做到这一点。如果有人可以提供帮助,那就太棒了。

【问题讨论】:

标签: r dplyr tidyr


【解决方案1】:

您可以使用data.table 执行以下操作。

首先,我定义了一个应用于数值向量的函数,它输出元素相对于向量中位数的对应位置:

med_fn = function(x){

  med = median(x)
  unlist(sapply(x, function(x){
    if(x > med) {'Above'} 
    else if(x < med) {'Below'}
    else {'At'}
  }))

}

> med_fn(c(1,2,3))
[1] "Below" "At"    "Above"

让我们检查一些示例数据:

dt = data.table(
  C1 = c(1, 2, 3),
  C2 = c(2, 1, 3),
  C3 = c(3, 2, 1)
)

old = c('C1', 'C2', 'C3') # Name of columns I want to perform operation on
new = paste0(old, '_medfn') # Name of new columns following operation

使用来自data.table.SD.SDcols 参数,我将med_fn 应用于old 列,在我的例子中是C1C2C3 列。我将新列称为C#_medfn

dt[, (new) := lapply(.SD, med_fn), .SDcols = old]

结果:

> dt
   C1 C2 C3 C1_medfn C2_medfn C3_medfn
1:  1  2  3    Below       At    Above
2:  2  1  2       At    Below       At
3:  3  3  1    Above    Above    Below

【讨论】:

    猜你喜欢
    • 2017-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 2019-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多