【问题标题】:Create multiple dataframes by filtering subsets that are not equal to a value in R通过过滤不等于 R 中的值的子集来创建多个数据帧
【发布时间】:2019-10-02 22:01:34
【问题描述】:

我有一个包含两列文本和颜色的数据框。

library(tidyverse)
library(purrr)

# sample dataframe
df <- data.frame(Text = c("text1", "text2", "text3", "text4"), 
                 Colours = c("blue", "white", "green", "yellow"), stringsAsFactors = F)


我需要的是一个数据框,比如说,NOT_Blue,它包括除包含“蓝色”的行之外的所有行。换句话说,一个具有所有颜色的数据框,除了那些不等于“蓝色”的颜色。最后我想把这些数据帧写成 csv 文件。

对于一个使用dplyr::filter!=(不相等)的数据框会起作用

not_blue <- df %>% filter(!Colours == "blue")

not_blue
   Text Colours
1 text2   white
2 text3   green
3 text4  yellow

问题是我需要为每种颜色/类别创建不同的数据框。

我想我需要使用其中一个 apply/map 系列函数。所以我创建了一个带有颜色的矢量,希望在函数中使用它。

# colours to feed the function
colours <- c("blue", "white", "green", "yellow")

# trying to make a function

remaining_colours <- function(x) {

  df <- df %>% filter(!Colours == x)
}


# using the formula with map_df of purrr
map_df(colours, remaining_colours) %>% arrange(Text)

# epic fail results
Text Colours
1  text1    blue
2  text1    blue
3  text1    blue
4  text2   white
5  text2   white
6  text2   white
7  text3   green
8  text3   green
9  text3   green
10 text4  yellow
11 text4  yellow
12 text4  yellow

您能帮我或说明如何为这种情况制作应用/映射/循环吗?

提前致谢!

【问题讨论】:

    标签: r function dataframe filter lapply


    【解决方案1】:

    这是一种使用lapply 的方法。这将创建您所需数据帧的列表。

    colours <- c("blue", "white", "green", "yellow")
    
    result <- lapply(colours, function(x) {
                 df %>% filter(!Colours == x)
              }) %>% 
              setNames(paste0("NOT_", colours))
    
    result
    
    $NOT_blue
       Text Colours
    1 text2   white
    2 text3   green
    3 text4  yellow
    
    $NOT_white
       Text Colours
    1 text1    blue
    2 text3   green
    3 text4  yellow
    
    $NOT_green
       Text Colours
    1 text1    blue
    2 text2   white
    3 text4  yellow
    
    $NOT_yellow
       Text Colours
    1 text1    blue
    2 text2   white
    3 text3   green
    

    【讨论】:

    • 非常感谢!如何将结果导出/写入为 csv 文件?
    • @yiah 你可以做到-lapply(seq_along(result), function(f) { write.csv(result[[f]], file = paste0(names(result)[f], ".csv"), row.names = F) })
    【解决方案2】:

    在函数内部,它是colours,而不是Colours

    map_df(colours, ~ df %>% 
                          filter(Colours != .x))
    
    #    Text Colours
    #1  text2   white
    #2  text3   green
    #3  text4  yellow
    #4  text1    blue
    #5  text3   green
    #6  text4  yellow
    #7  text1    blue
    #8  text2   white
    #9  text4  yellow
    #10 text1    blue
    #11 text2   white
    #12 text3   green
    

    如果我们需要listdata.frame,而不是map_df,只需使用map

    set_names(map(colours, ~ df %>% 
                          filter(Colours != .x)), paste0("df_", colours))
    

    或者把函数改成

    remaining_colours <- function(x) {
    
         df %>% 
             filter(!Colours == x)
      }
    

    【讨论】:

    • 非常感谢!两种解决方案都是有效的。在我的情况下,map_df 可能更方便,因为所有内容都转到一个 data.frame。在这种情况下,我需要一个颜色不匹配的列map_df(colours, ~ df %&gt;% filter(Colours != .x) %&gt;% mutate("NOT matching colour" = .x))
    猜你喜欢
    • 2018-06-23
    • 2018-06-07
    • 1970-01-01
    • 2021-01-05
    • 1970-01-01
    • 2020-08-21
    • 2021-12-28
    • 1970-01-01
    • 2021-09-02
    相关资源
    最近更新 更多