【问题标题】:apply ntile function to list of data frames with different bucket sizes将 ntile 函数应用于具有不同存储桶大小的数据帧列表
【发布时间】:2020-05-04 16:08:47
【问题描述】:

我想使用dplyr 中的ntile 函数或数据框列表上的类似函数,但对每个数据框使用不同的n。我的列表包含 150 个数据框,因此像下面这样的手动解决方案将不起作用。如何重写下面的代码以作用于数据框列表并返回带有新列的数据框列表?

library(tidyverse)
iris_list=split(iris,iris$Species)

iris_setosa=iris_list[[1]]
iris_versicolor=iris_list[[2]]
iris_virginica=iris_list[[3]]
iris_setosa$n3=ntile(iris_setosa$Sepal.Length,3)
iris_versicolor$n5=ntile(iris_setosa$Sepal.Length,5)
iris_virginica$n7=ntile(iris_setosa$Sepal.Length,7) 

最终的结果应该是这样的

final_list=list(iris_setosa,iris_versicolor,iris_virginica)



head(final_list[[1]])
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species n3
1          5.1         3.5          1.4         0.2  setosa  2
2          4.9         3.0          1.4         0.2  setosa  1
3          4.7         3.2          1.3         0.2  setosa  1
4          4.6         3.1          1.5         0.2  setosa  1
5          5.0         3.6          1.4         0.2  setosa  2
6          5.4         3.9          1.7         0.4  setosa  3

【问题讨论】:

    标签: r dplyr data-manipulation


    【解决方案1】:

    有几种方法可以实现这一点,具体取决于您最终想要什么类型的对象。

    一种方法是像这样使用base::expand.gridpurrr::pmap

    percentiles = list(3,5,7)
    iris_list %>% 
      map("Sepal.Length") %>% 
      expand.grid(percentiles) %>% 
      pmap(~ntile(..1,..2))
    

    首先,您只需要所有数据集的 Sepal.Length 变量,因此您使用 purrr::map 来获取它们。

    然后,expand.grid 创建一个包含所有参数组合的数据框。在这里,有 3 个成员的 2 个列表,它将返回一个 3x3=9 行的数据框:setosa 3versicolor 3virginica 3setosa 5、...

    最后,pmap 可以遍历数据帧并应用函数ntile,第一列 (iris_list) 作为第一个参数,第二列 (percentiles) 作为第二个参数。不幸的是,purrr 在处理名称方面非常糟糕,但似乎是故意的。

    编辑:

    您的编辑不知何故是另一个问题,所以这里是另一个答案:

    iris_list %>%
       map(~mutate(.x, n3=ntile(Sepal.Length,3)), 
                   n5=ntile(Sepal.Length,5)), n7=ntile(Sepal.Length,7)))
    

    【讨论】:

    • 代码使我的列表大小增加了三倍,我需要返回原始数据框并添加来自 ntile 的新列。我该如何修改以获得该结果?
    • 谢谢。这主要是可行的,我将编辑我的问题以明确我想要的解决方案我想我可能解释得不好。
    • @tetime 这里是另一个答案
    • @tetime 我想这还不是你想要的。我可能错误地假设了一件事,您确实需要所有 3 个数据集的 n3、n5 和 n7,对吗?
    • @Dan 您之前的回答有效,唯一缺少的是带来我需要的原始数据框。使用您的新解决方案,我必须在 mutate 语句中手动输入 150 行。很抱歉造成混乱,感谢您的帮助。
    【解决方案2】:

    我找到了一种可行的方法

    n_size=data.frame(Species=c("setosa ","versicolor","virginica"),size=c(3,5,7))
    iris_bin=iris %>% inner_join(n_size,by="Species") %>%
                      group_by(Species)%>% 
                      mutate(bin=ntile(Sepal.Length,size[1])) %>% 
                      arrange(Species,Sepal.Length,bin)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-29
      • 2017-03-09
      • 2022-11-23
      相关资源
      最近更新 更多