如何将这个精巧的用例转换为dplyr?

如何将这个精巧的用例转换为dplyr?,r,dplyr,tidyverse,R,Dplyr,Tidyverse,在使用predict.knn3时,我遇到了一个有趣的数据争论用例。我不知道我可以使用参数type=class调用predict来获得预测的级别,这正是我所需要的。因此,我制定了一个有点复杂的解决方案,从每个预测的结果行中选择概率最大的级别。这个问题是由于names函数不是以向量形式与矩阵一起工作,而是只与向量一起工作 要在了解type=class参数前后演示用例,请执行以下操作: rm(list = ls()) library(caret) library(tidyverse) library(

在使用predict.knn3时,我遇到了一个有趣的数据争论用例。我不知道我可以使用参数type=class调用predict来获得预测的级别,这正是我所需要的。因此,我制定了一个有点复杂的解决方案,从每个预测的结果行中选择概率最大的级别。这个问题是由于names函数不是以向量形式与矩阵一起工作,而是只与向量一起工作

要在了解type=class参数前后演示用例,请执行以下操作:

rm(list = ls())
library(caret)
library(tidyverse)
library(dslabs)

data("tissue_gene_expression")
x <- tissue_gene_expression$x
y <- tissue_gene_expression$y

set.seed(1)
test_index <- createDataPartition(y, times = 1, p = 0.5, list = FALSE)
test_x <- x[test_index,]
test_y <- y[test_index]
train_x <- x[-test_index,]
train_y <- y[-test_index]

# fit the model, predict without type="class" and use sapply to build the y_hat levels
fit <- knn3(train_x, train_y, k = 1)
pred <- predict(fit, test_x)
y_hat <- sapply(1:nrow(pred), function(i) as.factor(names(pred[i,which.max(pred[i,])])))

# compare it to the solution using predict with type="class"
identical(y_hat, as.factor(predict(fit, test_x, type="class")))
[1] TRUE
假设不知道predict.knn3函数中的这个方便类型=类;有没有更简单的方法使用tidyverse和dplyr来替换sapply?或者其他更简单的方法来实现这个用例

y_hat <- sapply(1:nrow(pred), function(i) as.factor(names(pred[i, which.max(pred[i,])])))

我必须使用melt将矩阵转换为长格式:

library(reshape2)
melt(pred) %>% 
    group_by(Var1) %>% 
    top_n(1,wt=value) %>% pull(Var2)

我必须使用melt将矩阵转换为长格式:

library(reshape2)
melt(pred) %>% 
    group_by(Var1) %>% 
    top_n(1,wt=value) %>% pull(Var2)

由于预测是一个矩阵,因此可以直接将which.max应用于每一行


pred由于预测是一个矩阵,您可以直接将which.max应用于每一行

pred见?最大列:

请参阅?max.col:


我发现使用dplyr对行进行操作可能有点混乱。不过这应该行得通。猜测一下,这不是计算效率最高的

solution <- as_tibble(predict(fit, test_x)) %>%
  rowwise() %>%
  do(as.data.frame(.) %>%
       mutate(., y_hat = names(.)[which.max(select(., everything()))])
  )

solution %>%
  slice(18:22)

# A tibble: 5 x 8
  cerebellum colon endometrium hippocampus kidney liver placenta y_hat     
       <dbl> <dbl>       <dbl>       <dbl>  <dbl> <dbl>    <dbl> <chr>     
1          1     0           0           0      0     0        0 cerebellum
2          1     0           0           0      0     0        0 cerebellum
3          0     1           0           0      0     0        0 colon     
4          0     1           0           0      0     0        0 colon     
5          0     1           0           0      0     0        0 colon

我发现使用dplyr对行进行操作可能有点混乱。不过这应该行得通。猜测一下,这不是计算效率最高的

solution <- as_tibble(predict(fit, test_x)) %>%
  rowwise() %>%
  do(as.data.frame(.) %>%
       mutate(., y_hat = names(.)[which.max(select(., everything()))])
  )

solution %>%
  slice(18:22)

# A tibble: 5 x 8
  cerebellum colon endometrium hippocampus kidney liver placenta y_hat     
       <dbl> <dbl>       <dbl>       <dbl>  <dbl> <dbl>    <dbl> <chr>     
1          1     0           0           0      0     0        0 cerebellum
2          1     0           0           0      0     0        0 cerebellum
3          0     1           0           0      0     0        0 colon     
4          0     1           0           0      0     0        0 colon     
5          0     1           0           0      0     0        0 colon
如果您这样做,我将使用tidyr now和pivot_更长时间。根据github页面:Regrape2已失效:将只进行必要的更改以使其保持在CRAN上。我们建议改为使用tidyr。如果你这样做,我会使用tidyr现在与pivot_更长时间。根据github页面:Regrape2已失效:将只进行必要的更改以使其保持在CRAN上。我们建议改用tidyr。@天行者请参阅编辑dplyr方法。它应该很快,因为max.colvectorized@SkyWalker请参见编辑dplyr方法。它应该是快速的,因为max.col是矢量化的
solution <- as_tibble(predict(fit, test_x)) %>%
  rowwise() %>%
  do(as.data.frame(.) %>%
       mutate(., y_hat = names(.)[which.max(select(., everything()))])
  )

solution %>%
  slice(18:22)

# A tibble: 5 x 8
  cerebellum colon endometrium hippocampus kidney liver placenta y_hat     
       <dbl> <dbl>       <dbl>       <dbl>  <dbl> <dbl>    <dbl> <chr>     
1          1     0           0           0      0     0        0 cerebellum
2          1     0           0           0      0     0        0 cerebellum
3          0     1           0           0      0     0        0 colon     
4          0     1           0           0      0     0        0 colon     
5          0     1           0           0      0     0        0 colon