0

问题:

我有一个函数,它使用一个参数来索引一个 internal data.frame,但返回一个整数。但是,当我运行该函数dplyr::mutate以基于 a 中的另一个变量创建新变量时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

但是,如果我想用 atibbledata.framewith中的变量的每个元素来计算函数mutate,它会失败:

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

如果我们只使用 的前 4 行(或更少)toydat并注意内部data.frameintoyfun是 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 行,那么遍历 internal 的索引值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以便我可以保持工作流程一致?

4

1 回答 1

2

问题是因为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

这不会给出任何错误。

要解决错误,我们可以使用uniqueunique获取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,并将每个单独的值一个一个地发送到函数

toydat %>% 
   rowwise() %>%
   mutate(thing4 = toyfun(thing1 = thing1))

#Called from: toyfun(thing1 = thing1)
#Browse[1]> thing1
#[1] 4

toydat %>% 
  rowwise() %>%
  mutate(thing4 = toyfun(thing1 = thing1))

#  thing1 thing4
#   <dbl>  <dbl>
#1      4      5
#2      3      4
#3      2      3
#4      1      2
#5      1      2
#6      2      3

希望这是清楚和有帮助的。

于 2018-12-07T02:45:18.880 回答