【问题标题】:Add column to a data frame that is the result of a function that takes multiple columns -- row-wise -- as an input vectors将列添加到数据框中,该数据框是采用多列(逐行)作为输入向量的函数的结果
【发布时间】:2019-08-02 15:25:21
【问题描述】:

我认为会扩展到我的问题的My previous question不够具体,所以我再次重新审视:

我的实际数据框有更多列。

library(tidyverse) 
# not installed in session but needed to reference:
# laeken::gini

df <- data.frame(a1 = c(1:5), 
                 b1 = c(3,1,3,4,6), 
                 c1 = c(10:14), 
                 a2 = c(9:13), 
                 b2 = c(3:7), 
                 c2 = c(15:19))

> df
  a1 b1 c1 a2 b2 c2
1  1  3 10  9  3 15
2  2  1 11 10  4 16
3  3  3 12 11  5 17
4  4  4 13 12  6 18
5  5  6 14 13  7 19

我想使用tidyversemutatedf 添加一列,这是输出函数my_gini 的结果(如下所示):

my_gini <- function(some_vector){
  incs = c(1,2,5,9)
  laeken::gini(inc = incs, weights = some_vector)
}

此函数需要采用一个向量,该向量将由来自df 的多个不同列值组成,定义为my_cols

my_cols = c("b1","c1", "b2","c2")

我怀疑我需要在这里使用purrr,例如:

df %>% 
  mutate(my_g = pmap_dbl(
    select(., my_cols), ~ c(...) %>% 
      {my_gini(.[my_cols])}
    ))

应该在df 中添加一列my_g,这样第一行将是:

my_gini(c(3,10, 3,15)) # 32.5564

第二行是:

my_gini(c(1,11,4,16))  # 29.66243

等等。

但是,它不起作用。我收到一个错误:

Error: Result 1 is not a length 1 atomic vector

sum 执行相同的操作效果很好,所以我不确定为什么它在这里不起作用。

df %>% 
  mutate(my_g = pmap_dbl(
    select(., my_cols), ~ c(...) %>% 
      {sum(.[my_cols])}
    ))

提前谢谢你。

【问题讨论】:

  • my_gini 返回一个列表,查看my_gini(as.numeric(df[1,my_cols]))my_gini(as.numeric(df[1,my_cols]))[[1]] 之间的区别,因此您的第一个代码可以正常工作,只需将{my_gini(.[my_cols])} 更改为{my_gini(.[my_cols])[[1]]}
  • 谢谢 - 这比使用 unlist 更干净。

标签: r purrr


【解决方案1】:

尝试只使用pmappmap_dbl

df %>% 
  mutate(my_g = unlist(pmap(
    select(., my_cols), ~ c(...) %>% 
      {my_gini(.[my_cols])}
    )))

  a1 b1 c1 a2 b2 c2     my_g
1  1  3 10  9  3 15  32.5564
2  2  1 11 10  4 16 29.66243
3  3  3 12 11  5 17 32.32696
4  4  4 13 12  6 18 33.26741
5  5  6 14 13  7 19  34.8913

pmap_dbl 期望输入数字,但您的函数创建了 S3 类 gini/indicator 的对象。当我用pmap_dbl 运行它时,我收到了这个警告:

Error: Evaluation error: Result 1 must be a single double, not a vector of class `gini/indicator` and of length 10

所以这涉及到 R 的一些更高级的计算机编程元素,但基本上你的函数创建了一种类型的对象,它不是基础 R 的原生对象,并且不会总是像你发现的那样与其他对象一起玩得很好函数/包。

因此,要了解更多细节以及为什么不能将其强制转换为数字,您需要查看您的函数实际创建的内容。当您强制转换为字符串时,您会得到以下结果:

1  list(value = 32.556404997203, valueByStratum = NULL, varMethod = NULL, var = NULL, varByStratum = NULL, ci = NULL, ciByStratum = NULL, alpha = NULL, years = NULL, strata = NULL)
2 list(value = 29.6624331550802, valueByStratum = NULL, varMethod = NULL, var = NULL, varByStratum = NULL, ci = NULL, ciByStratum = NULL, alpha = NULL, years = NULL, strata = NULL)
3 list(value = 32.3269611074489, valueByStratum = NULL, varMethod = NULL, var = NULL, varByStratum = NULL, ci = NULL, ciByStratum = NULL, alpha = NULL, years = NULL, strata = NULL)
4 list(value = 33.2674137552186, valueByStratum = NULL, varMethod = NULL, var = NULL, varByStratum = NULL, ci = NULL, ciByStratum = NULL, alpha = NULL, years = NULL, strata = NULL)
5 list(value = 34.8913043478261, valueByStratum = NULL, varMethod = NULL, var = NULL, varByStratum = NULL, ci = NULL, ciByStratum = NULL, alpha = NULL, years = NULL, strata = NULL)```

【讨论】:

  • 运行但my_g 列中的所有行都显示&lt;S3: gini&gt;
  • 以上评论基于df的RStudio视图。如果我在控制台中运行它确实以正确的输出值运行,我什至不知道这意味着什么。
  • 是的 - 如果我按照你的建议使用 pmapmy_g 的每一行都是“列表”类型的 s3 对象 - 试图强制 as.double 不起作用。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
  • 2022-09-27
  • 1970-01-01
  • 2017-09-16
  • 2021-07-02
相关资源
最近更新 更多