dplyr嵌套ifelse错误 - 它是矢量回收吗?

时间:2017-12-29 02:50:21

标签: r dplyr

我可以编写这个代码,为虹膜数据集添加两列。第一个添加的列是前四列的总和。第二个添加的专栏是我尝试编程"。

iris.size <- iris %>% 
  mutate(Total = 
           apply(.[(1:4)], 1, sum)
         ) %>% 
  mutate(Size = 
           ifelse(
             apply(.[(1:4)], 1, sum) != 0 & 
               .[2] > .[3], "Output1", 
             ifelse(
               apply(.[(1:4)], 1, sum) == 0 & 
                 .[2] > .[3], "Output2", 
               "Output3")
             )
         )

您会注意到此代码不会抛出任何错误,它会输出我想要输出的内容。但是看看当我尝试分析的下一步时会发生什么。

iris.size %>% arrange(Size)
  

错误:列Size必须是1d原子向量或列表

这一定是我的ifelse逻辑。正确? Ifelse逻辑似乎很简单。如果条件1 而不是output1,否则如果条件2 而不是output2否则 output3。< / p>

我最终使用as.vector iris.size $ Size 强制转换为矢量但我想知道我的逻辑首先出错了所以我不# 39;将来不得不求助于使用乐队助手。经过一些谷歌搜索后,听起来if语句优于R中的ifelse语句,但if语句似乎只适用于单个逻辑值,而不是向量。

3 个答案:

答案 0 :(得分:1)

利用rowwise并将某些事情分解为可读性......

iris.size <- iris %>% 
  mutate(Total = 
           apply(.[(1:4)], 1, sum)
  )
iris.size <-iris.size %>% rowwise %>%  mutate(Size = 
           if(
            Total != 0 && Sepal.Width > Petal.Length)  {
             "Output1"
             } else {
             if(Total == 0 && Petal.Length > Petal.Length){
               "Output2"
             } else { 
               "Output3"}}
)
class(iris.size$Size)
[1] "character"


> iris.size %>% arrange(Size)
# A tibble: 150 x 7
   Sepal.Length Sepal.Width Petal.Length Petal.Width
          <dbl>       <dbl>        <dbl>       <dbl>
 1          5.1         3.5          1.4         0.2
 2          4.9         3.0          1.4         0.2
 3          4.7         3.2          1.3         0.2
 4          4.6         3.1          1.5         0.2
 5          5.0         3.6          1.4         0.2
 6          5.4         3.9          1.7         0.4
 7          4.6         3.4          1.4         0.3
 8          5.0         3.4          1.5         0.2
 9          4.4         2.9          1.4         0.2
10          4.9         3.1          1.5         0.1
# ... with 140 more rows, and 3 more variables:
#   Species <fctr>, Total <dbl>, Size <chr>
> 

答案 1 :(得分:1)

运行代码时,您将此输出显示为iris.size

  Sepal.Length Sepal.Width Petal.Length Petal.Width Species Total Sepal.Width
1          5.1         3.5          1.4         0.2  setosa  10.2     Output1
2          4.9         3.0          1.4         0.2  setosa   9.5     Output1
3          4.7         3.2          1.3         0.2  setosa   9.4     Output1
4          4.6         3.1          1.5         0.2  setosa   9.4     Output1
5          5.0         3.6          1.4         0.2  setosa  10.2     Output1
6          5.4         3.9          1.7         0.4  setosa  11.4     Output1

它未显示Size的原因是因为尚未创建列Size。之所以发生这种情况,是因为您将类data.frame()的两个对象与.[2] > .[3]进行比较,而不是将.[, 2] > .[, 3]与两个向量进行比较。

我仍在努力了解正在创作的内容。什么是Sepal.Width列?

使用以下内容调整:

iris.size <- iris %>%    mutate(Total = 
           apply(.[(1:4)], 1, sum)   ) %>%    mutate(Size = 
           ifelse(
             apply(.[(1:4)], 1, sum) != 0 & 
               .[,2] > .[,3], "Output1", 
             ifelse(
               apply(.[(1:4)], 1, sum) == 0 & 
                 .[,2] > .[,3], "Output2", 
               "Output3")
           )   )

iris.size
Sepal.Length Sepal.Width Petal.Length Petal.Width Species Total    Size
1          5.1         3.5          1.4         0.2  setosa  10.2 Output1
2          4.9         3.0          1.4         0.2  setosa   9.5 Output1
3          4.7         3.2          1.3         0.2  setosa   9.4 Output1
4          4.6         3.1          1.5         0.2  setosa   9.4 Output1
5          5.0         3.6          1.4         0.2  setosa  10.2 Output1
6          5.4         3.9          1.7         0.4  setosa  11.4 Output1

<强>建议:

如果您感兴趣,这是您的代码的精简版本。如果需要,您可以将Sepal.WidthSepal.Length替换为.[,2].[,3]

iris.size <- iris %>% 
             mutate(Total = rowSums(.[,sapply(., is.numeric)]),
                    Size = ifelse(Total != 0 & Sepal.Width > Sepal.Length, "Output1", 
                           ifelse(Total == 0 & Sepal.Width > Sepal.Length, "Output2", "Output3")))%>%
             arrange(Size)

iris.size
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species Total    Size
1          5.1         3.5          1.4         0.2  setosa  10.2 Output1
2          4.9         3.0          1.4         0.2  setosa   9.5 Output1
3          4.7         3.2          1.3         0.2  setosa   9.4 Output1
4          4.6         3.1          1.5         0.2  setosa   9.4 Output1
5          5.0         3.6          1.4         0.2  setosa  10.2 Output1
6          5.4         3.9          1.7         0.4  setosa  11.4 Output1

答案 2 :(得分:0)

错误消息是由iris.size["Size"]data.frame()类型的对象引起的。这可以通过str()函数确认:

> str(iris.size["Size"])
'data.frame':   150 obs. of  1 variable:
 $ Size: chr [1:150, 1] "Output1" "Output1" "Output1" "Output1" ...
  ..- attr(*, "dimnames")=List of 2
  .. ..$ : NULL
  .. ..$ : chr "Sepal.Width"
> 

使用as.vector()转换对象可以解决问题,因为数据框包含1列。