【问题标题】:How to create new column (using dplyr's mutate) based on conditions applied on the entire piped dataframe如何根据应用于整个管道数据帧的条件创建新列(使用 dplyr 的 mutate)
【发布时间】:2021-12-29 16:57:39
【问题描述】:

我正在寻找一种基于某些“条件”创建新列(使用 dplyr 的 mutate)的方法。

library(tidyverse)

qq <- 5

df <- data.frame(rn = 1:qq,
           a = rnorm(qq,0,1),
           b = rnorm(qq,10,5))

myf <- function(dataframe,value){
  result <- dataframe %>% 
    filter(rn<=value) %>% 
    nrow
  return(result)
}

上面的例子是一个相当简化的版本,我试图过滤管道数据帧 (df) 并获得一个新列 (foo),其值将描述 rn 小于或等于当前的行数rn (每一行的 rn - 来自管道 df )。您可以在下面看到我得到的输出与我期望得到的输出:

df %>% 
  mutate(
    foo_i_am_getting = myf(.,rn),
    foo_expected = 1:qq)

         rn          a         b foo_i_am_getting foo_expected
1  1 -0.5403937 -4.945643                5            1
2  2  0.7169147  2.516924                5            2
3  3 -0.2610024 -7.003944                5            3
4  4 -0.9991419 -1.663043                5            4
5  5  1.4002610 15.501411                5            5

我尝试执行的实际计算比较麻烦,但是,如果我解决了上述简化版本,我相信我可以处理自定义函数中的其余操作/计算。

BONUS QUESTION : 目前,我想在其上应用过滤器的列的名称(即 rn)在自定义函数中硬编码(filter(rn)。如果这是自定义函数的参数,以 'tidyverse' 样式传递,那就太好了 - 即 不带引号 - 例如myf

免责声明:我已尽力描述手头的问题,但是,如果仍有不清楚的地方,请告诉我,以便我进一步详细说明。

提前感谢您的支持!

【问题讨论】:

  • 您的foo_expected 应该是2,4,3,1,5...对吗?

标签: r dplyr tidyverse


【解决方案1】:

您需要一步一步来,因为现在您将整个向量传递给过滤器,而不是每次只传递一个值:

df %>% 
  mutate(
    foo_i_am_getting = map_dbl(.$rn, function(x) nrow(filter(., rn <= x))),
    foo_expected = 1:qq)

现在我们传递 1 来过滤 rn 列(函数返回行数),然后 2 来过滤 rn 列。

功能可能是:

myf <- function(vec_filter, dataframe, vec_rn) {
  map_dbl(vec_filter, ~ nrow(filter(dataframe, {{vec_rn}} <= .x)))
}

df %>% 
  mutate(
    foo_i_am_getting = map_dbl(.$rn, function(x) nrow(filter(., rn <= x))),
    foo_expected = 1:qq,
    foo_function = myf(rn, ., rn))

【讨论】:

  • 似乎工作得很好!非常感谢您的及时回复并首先解释我的错误!欣赏它
猜你喜欢
  • 1970-01-01
  • 2018-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-23
  • 1970-01-01
  • 2020-09-21
  • 2021-03-13
相关资源
最近更新 更多