dplyr mutate函数调用返回错误的值

Nat*_*Nat 0 r dplyr

有人可以解释为什么下面的dplyr mutate调用,其中我应用一个函数将一列作为参数来设置新列的值,不起作用?它似乎没有在正确的值上调用函数:新season列是根据列中的第一个值mon而不是其自己的行中的值来设置的.

# Function to return season (winter, summer, or transition) given numerical month
getSeason <- function(m) {
  if(m >= 11 || m <= 3) 
    return(as.factor("Winter"))
  if(m >= 5 && m <= 9) 
    return(as.factor("Summer"))
  return(as.factor("Trans"))
}

getSeason(5) # Works: returns "Summer"

mon <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
months <- as.data.frame(mon)

months %>% mutate(season=getSeason(mon))  # doesn't work: all seasons set as "Winter"
Run Code Online (Sandbox Code Playgroud)

我正在使用R版本3.2.4和dplyr的最新开发版本.(这也不适用于最新版本的dplyr.)

joh*_*nes 5

您还可以使用Vectorize

# Function to return season (winter, summer, or transition) given numerical month
getSeason <- function(m) {
  if(m >= 11 || m <= 3) 
    return(as.factor("Winter"))
  if(m >= 5 && m <= 9) 
    return(as.factor("Summer"))
  return(as.factor("Trans"))
}


getSeason <- Vectorize(getSeason)

mon <- c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)
months <- data.frame(mon = mon)

months %>% mutate(season=gs(mon)) 
Run Code Online (Sandbox Code Playgroud)


aos*_*ith 5

其他答案很好地解释了为什么你遇到这个问题.

我认为这是新功能case_when可以派上用场的情况(目前在开发版本中可用,dplyr_0.4.3.9001).

目前你必须使用美元符号表示法在case_when里面使用mutate.

months %>% mutate(season = case_when(.$mon >= 11 | .$mon <= 3 ~ "Winter",
                                     .$mon >= 5 & .$mon <= 9 ~ "Summer",
                                     TRUE ~ "Trans"))

   mon season
1    1 Winter
2    2 Winter
3    3 Winter
4    4  Trans
5    5 Summer
6    6 Summer
7    7 Summer
8    8 Summer
9    9 Summer
10  10  Trans
11  11 Winter
12  12 Winter
Run Code Online (Sandbox Code Playgroud)

您可以使用case_when而不是ififelse(或新的dplyr函数if_else)来构建函数.对我来说,语法似乎更像是使用而if不是嵌套ifelse.

getSeason <- function(m) {
    factor(
        case_when(
            m >= 11 | m <= 3 ~ "Winter",
            m >= 5 & m <= 9 ~ "Summer",
            TRUE ~ "Trans"
            ) 
        )
}

months %>% mutate(season=getSeason(mon))

   mon season
1    1 Winter
2    2 Winter
3    3 Winter
4    4  Trans
5    5 Summer
6    6 Summer
7    7 Summer
8    8 Summer
9    9 Summer
10  10  Trans
11  11 Winter
12  12 Winter
Run Code Online (Sandbox Code Playgroud)

请注意,"其他所有"条件是最后完成的case_when,您只需要TRUE在公式的左侧放置以使用最终值填充其他所有内容.