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

问题描述 投票:0回答:3

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

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

我最终使用as.vector将iris.size $ Size强制转换为矢量,但我想知道我的逻辑首先出现在哪里,所以我不必在将来使用band aids。在一些谷歌搜索后,听起来像if语句优于R中的ifelse语句,但if语句似乎只适用于单个逻辑值,而不是向量。

r dplyr
3个回答
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

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>
> 

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列。

© www.soinside.com 2019 - 2024. All rights reserved.