如何在R语言的map函数中使用ifelse?

6
我在map函数中使用ifelse语句出现问题:

我在使用map函数时遇到了ifelse语句的问题:

df<-list(mtcars,mtcars)

我只想以如下方式组织此列表中的每个数据框:slice(x,c(n(),2:(n()-1),1))
map(df, ~   slice(.x,c(n(),2:(n()-1),1)))   # it works well. 

但是如果我在条件x$cyl == 4中设置时,无法在ifelse中执行此操作:

map(df, ~   ifelse(sum(.x$cyl == 4) > 0, slice(.x,c(n(),2:(n()-1),1)), .x)) # The output is weird

我尝试使用lapply做同样的事情,但它没有起作用:

lapply(df, function(x) ifelse(sum(x$cyl == 4) > 0, slice(x,c(n(),2:(n()-1),1)),x))

需要帮忙吗?


我看到了你对Alec B的澄清评论,所以根据你提供的信息,我改变了我的答案。map_if函数应该能解决问题。 - www
1
当您确定所有参数具有相同的长度时,使用ifelse。在这里,最好使用if/else。根据文档,“值-与测试和数据值的属性(包括维度和“类”)相同的向量,从是或否的值中获取数据值。”'test'是逻辑向量,这是正确的,但长度为1。'yes'是一个数据框/ tibble而不是向量,并且行数与'no'不同。您可以将其包装在list中以获得'yes','no'的长度1。但是,在这里我避免使用ifelse。 - akrun
2个回答

5
我们可以使用 map_if 只在条件为真时应用函数。
library(tidyverse)

df <- list(mtcars,mtcars)

df2 <- map_if(df, .p = function(y) any(y$cyl == 4),
                  .f = ~slice(.x, c(n(), 2:(n()-1), 1)))

但是为什么 ifelsemap 内部不起作用呢? - AnilGoyal
1
@AnilGoyal 我不完全知道原因。可能是因为 ifelse 函数期望一个向量作为输入。 - www

3

这种方法检查列表中每个数据框是否存在 cyl == 4 的行。如果满足该条件,则返回所需的切片。否则,将返回未更改的数据框。

library(dplyr)


df<-list(mtcars,mtcars)



lapply(df, function(x) {
  if (any(x$cyl == 4)) {
    slice(x, c(n(), 2:(n()-1), 1)) 
    } else { 
      x 
    }
  })

如果您强烈偏好使用map
library(dplyr)
library(purrr)

df<-list(mtcars,mtcars)



map(df, ~ 
  if (any(.x$cyl == 4)) {
    slice(.x, c(n(), 2:(n()-1), 1)) 
    } else { 
      .x 
    }
  )

谢谢@Alec B。我明白你的意思。但是在我的主要代码中,我需要使用ifelse - Laura
你为什么需要使用ifelse呢?是因为你也想返回$cyl!=4的行吗? - Alec B
我需要在每个具有值为4cyl列中使用slice函数重新排序数据框。如果我的数据框中没有cyl列的值为4,则不执行任何操作。我的可重现示例应该有其他没有其列中值为4的数据框。我会尽快更改我的可重现示例。 - Laura
啊,我现在明白你的问题了。请查看我的修改后的答案。 - Alec B

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接