使用向量索引而不是内部数据的函数在带有dplyr :: mutate

时间:2018-12-07 02:22:31

标签: r dplyr

问题:

我有一个函数,该函数使用参数来索引内部data.frame,但返回一个整数。但是,当我在dplyr::mutate中运行该函数以基于data.frame中的另一个变量创建一个新变量时,出现错误:

Error in mutate_impl(.data, dots) : 
  Evaluation error: duplicate subscripts for columns.

这似乎是由于使用变量的索引位置而不是其值对数据帧进行内部索引所致。

我该如何解决?

示例:

在此函数中,我需要索引到内部data.frame并将其用于计算结果。 :连接和数据:

toyfun <- function(thing1){

  thing2 <- data.frame(a = 0, b = 0, c = 0, d = 0)
  thing2[, thing1] <- 1

  thing3 <- sum(thing2[1,]) + thing1

  return(thing3)
}


toydat <- tibble(thing1 = c(4, 3, 2, 1, 1, 2))

函数按预期运行:

toyfun(thing1 = toydat$thing1[1])
#[1] 5

但是,如果我想使用tibbledata.framemutate中的变量的每个元素来计算函数,它将失败:

toydat %>% 
  mutate(thing4 = toyfun(thing1 = thing1))
# Error in mutate_impl(.data, dots) : 
#  Evaluation error: duplicate subscripts for columns.

如果我们仅使用toydat的前4行(或更少),请注意data.frame中的内部toyfun的宽度为4列,效果很好

toydat[1:4,] %>% 
  mutate(thing4 = toyfun(thing1 = thing1))
# # A tibble: 4 x 2
#   thing1 thing4
#    <dbl>  <dbl>
# 1      4      5
# 2      3      4
# 3      2      3
# 4      1      2

但是,如果再次使用5行,那么遍历内部data.frame的索引值,就会再次失败:

toydat[1:5,] %>% 
  mutate(thing4 = toyfun(thing1 = thing1))
# Error in mutate_impl(.data, dots) : 
#   Evaluation error: duplicate subscripts for columns.

问题的根源

该结果似乎表明问题在于使用thing1的索引值而不是其实际值进行内部索引。这很奇怪,因为如上面的4行示例中所使用的那样,我们可以看到Thing4中的返回值与应使用thing1的值计算结果时的值相同。

注意:sapply不会发生相同的问题:

sapply(toydat$thing1, toyfun)
# [1] 5 4 3 2 2 3

dplyr类型框架中是否有解决此问题的想法,以便我可以保持工作流程的一致性?

1 个答案:

答案 0 :(得分:1)

问题是因为mutate将整个列一起发送到该函数。

让我们调试功能

toyfun <- function(thing1){
   browser()
   thing2 <- data.frame(a = 0, b = 0, c = 0, d = 0)
   thing2[,thing1] <- 1
   thing3 <- thing1 + 1
  return(thing3)
}

现在我们运行mutate命令

toydat %>% 
  mutate(thing4 = toyfun(thing1 = thing1))
#Called from: toyfun(thing1 = thing1)
#Browse[1]> thing1
#[1] 4 3 2 1 1 2

由于第1列有重复的条目,因此会出现错误。

相同
df <- mtcars
df[, c(5, 5)] <- 1
  

[<-.data.frame*tmp*,,c(1,1),value = 1)中的错误:     列的下标重复

现在让我们来看一下sapply通话

sapply(toydat$thing1, toyfun)
#Called from: FUN(X[[i]], ...)
#Browse[1]> thing1
#[1] 4

sapply一次传递值,因此没有错误。

相同
df <- mtcars
df[, 5] <- 1
df[, 5] <- 1

没有任何错误。

要解决该错误,我们可以使用unique仅获得unique的{​​{1}}个条目

thing1

,这也将继续与toyfun <- function(thing1){ thing2 <- data.frame(a = 0, b = 0, c = 0, d = 0) thing2[,unique(thing1)] <- 1 thing3 <- thing1 + 1 return(thing3) } toydat %>% mutate(thing4 = toyfun(thing1 = thing1)) # A tibble: 6 x 2 # thing1 thing4 # <dbl> <dbl> #1 4 5 #2 3 4 #3 2 3 #4 1 2 #5 1 2 #6 2 3

一起使用
sapply

如果您不想更改功能,另一种选择是使用sapply(toydat$thing1, toyfun) #[1] 5 4 3 2 2 3 ,其作用与rowwise相同,并将每个单独的值一个接一个地发送给功能

sapply

希望这很清楚而且很有帮助。