使用dplyr获取以变量为条件的R数据帧的第n行,第一行或最后一行

时间:2017-04-27 01:49:47

标签: r dplyr

因为nth(y,-1)返回的值不是数据帧而且我对row_number()或slice()没有成功到目前为止我想知道我是否遗漏了任何明显的或者应该重新考虑这种方法:

我创建了一个函数:

ranking <- function(df, state, num = "last"){
    ## Setting num for "last" condition to n() gives error
    num <- ifelse(num=="first", 1, ifelse(num=="last", -1, num)) 
    df %>%
        filter(State == state) %>%
        arrange(y, State) %>%
        slice(num)  ## Does not work for -1
}

所以对于下面的df:

df <- data.frame(State=c("TX","TX","TX","MD"),y=c(5,2,3,4))
   State y
1     TX 5
2     TX 2
3     TX 3
4     MD 4

我想返回以下适当的&#34;最后&#34;和第n个函数调用:

ranking(df, "TX", "last")
   State y
1     TX 5
ranking(df, "TX", 2)
   State y
1     TX 3

2 个答案:

答案 0 :(得分:2)

var result = digital_root(count); // get the digital root of count (may or may not call digital_root while calculating it, it's not owr concern)
return result;                    // return the result of that so it can be used from the caller of digital_root

答案 1 :(得分:1)

我们可以略微更改该功能,并使用quosure的devel版本中的新dplyr(即将发布0.6.0

library(dplyr)
rankingN <- function(dat, stateVal, num){

      state <- quo_name(enquo(stateVal))
      num <- quo_name(enquo(num))

      numF <- function(x, val) ifelse(x == "first", 1, ifelse(x == "last", val[1], x))

      dat %>%
          filter(State == state) %>%
          arrange(y, State) %>%
          mutate(n = n()) %>%
          slice(numF(num, n)) %>%
          select(-n)
 }

rankingN(df, TX, last)
# A tibble: 1 × 2
#   State     y
#  <fctr> <dbl>
#1     TX     5

rankingN(df, TX, first)    
# A tibble: 1 × 2
#   State     y
#   <fctr> <dbl>
#1     TX     2

rankingN(df, MD, first)
# A tibble: 1 × 2
#    State     y
#    <fctr> <dbl>
#1     MD     4

或者另一种选择是做一个双slice来返回第一个slice中的两行,然后根据case_when函数返回选择第一个或最后一个

rankingN1 <- function(dat, stateVal, num){

        state <- quo_name(enquo(stateVal))
        num <- quo_name(enquo(num))
        numF <- function(x) case_when(x == "first" ~1L, 
                                      x== "last" ~2L,
                                      TRUE ~NA_integer_)
         dat %>%
            filter(State == state) %>%
            arrange(y, State) %>%
            slice(c(1, n())) %>%
            slice(numF(num))

 }



rankingN1(df, TX, last)
# A tibble: 1 × 2
#   State     y
#  <fctr> <dbl>
#1     TX     5

rankingN1(df, TX, first)
# A tibble: 1 × 2
#   State     y
#  <fctr> <dbl>
#1     TX     2
 rankingN1(df, MD, first)
# A tibble: 1 × 2
#   State     y
#  <fctr> <dbl>
#1     MD     4

enquo接受输入参数并转换为quosure,而quo_name将其转换为字符串,用于需要作为字符串求值的地方。我们不是在n()中使用ifelse,而是根据它创建一个列,然后基于该列返回的值slice创建行

数据

df <- data.frame(State=c("TX","TX","TX","MD"),y=c(5,2,3,4))