【问题标题】:subset dataframe based on conditions in vector基于向量条件的子数据帧
【发布时间】:2014-02-18 14:20:15
【问题描述】:

我有两个数据框

#df1
type <- c("A", "B", "C")
day_start <- c(5,8,4)
day_end <- c(12,10,11)
df1 <- cbind.data.frame(type, day_start, day_end)
df1
  type day_start day_end
1    A         5      12
2    B         8      10
3    C         4      11

#df2
value <- 1:10
day <- 4:13
df2 <- cbind.data.frame(day, value)
   day value
1    4     1
2    5     2
3    6     3
4    7     4
5    8     5
6    9     6
7   10     7
8   11     8
9   12     9
10  13    10

我想对 df2 进行子集化,以便 df1 中的每个因子“类型”级别都有自己的数据框,仅包括该因子级别的 day_start 和 day_end 之间的行/天。

“A”的期望结果是..

list_of_dataframes$df_A
   day value
1    5     2
2    6     3
3    7     4
4    8     5
5    9     6
6   10     7
7   11     8
8   12     9

我在 SO 上找到了this question,答案是建议使用 mapply(),但是,我只是无法弄清楚我必须如何调整那里给出的代码以适应我的数据和期望的结果.. 有人可以帮帮我吗?

【问题讨论】:

    标签: r dataframe subset


    【解决方案1】:

    以下解决方案假设您拥有天数的所有整数值,但如果该假设是合理的,那么它是一个简单的单行:

    > apply(df1, 1, function(x) df2[df2$day %in% x[2]:x[3],])
    [[1]]
      day value
    2   5     2
    3   6     3
    4   7     4
    5   8     5
    6   9     6
    7  10     7
    8  11     8
    9  12     9
    
    [[2]]
      day value
    5   8     5
    6   9     6
    7  10     7
    
    [[3]]
      day value
    1   4     1
    2   5     2
    3   6     3
    4   7     4
    5   8     5
    6   9     6
    7  10     7
    8  11     8
    

    您可以使用setNames 来命名列表中的数据框:

    setNames(apply(df1, 1, function(x) df2[df2$day %in% x[2]:x[3],]),df1[,1])
    

    【讨论】:

      【解决方案2】:

      是的,你可以使用mapply

      定义一个函数来做你想做的事:

      fun <- function(x,y) df2[df2$day >= x & df2$day <= y,]
      

      然后使用mapply 将此函数应用于day_startday_end 的每个元素:

      final.output <- mapply(fun,df1$day_start, df1$day_end, SIMPLIFY=FALSE)
      

      这将为您提供一个包含所需输出的列表:

      final.output
      
      [[1]]
        day value
      2   5     2
      3   6     3
      4   7     4
      5   8     5
      6   9     6
      7  10     7
      8  11     8
      9  12     9
      
      [[2]]
        day value
      5   8     5
      6   9     6
      7  10     7
      
      [[3]]
        day value
      1   4     1
      2   5     2
      3   6     3
      4   7     4
      5   8     5
      6   9     6
      7  10     7
      8  11     8
      

      您可以将列表中的每个data.frame命名为setNames

      final.output <- setNames(final.output,df1$type)
      

      或者你也可以在列表的data.frames上放一个属性类型:

      fun <- function(x,y, type){
        df <- df2[df2$day >= x & df2$day <= y,]
        attr(df, "type") <- as.character(type)
        df
      }
      

      那么final.output 中的每个data.frame 都会有一个属性,以便您知道它是哪种类型:

      final.output <- mapply(fun,df1$day_start, df1$day_end,df1$type, SIMPLIFY=FALSE)
      
      # check wich type the first data.frame is 
      attr(final.output[[1]], "type")
      [1] "A"
      

      最后,如果您不想要包含 3 个 data.frames 的列表,您可以创建一个函数,将 3 个 data.frames 分配给全局环境:

      fun <- function(x,y, type){
        df <- df2[df2$day >= x & df2$day <= y,]
        name <- as.character(type)
        assign(name, df, pos=.GlobalEnv)
      }
      
      mapply(fun,df1$day_start, df1$day_end, type=df1$type, SIMPLIFY=FALSE)
      

      这将在名为 A、B 和 C 的全局环境中创建 3 个单独的 data.frame。

      【讨论】:

        猜你喜欢
        • 2012-11-17
        • 1970-01-01
        • 2019-10-13
        • 1970-01-01
        • 2019-10-22
        • 2022-01-14
        • 2023-03-09
        • 1970-01-01
        • 2020-11-15
        相关资源
        最近更新 更多