R - 创建一列字符矩阵

标签 r dplyr lapply

这是我的可重现的数据框:

library(tidyverse)
df <- structure(list(PN = c("41681", "16588", "34881", 
"36917", "33116", "68447"), `2017-10` = c(0L, 
0L, 0L, 0L, 0L, 0L), `2017-11` = c(0L, 1L, 0L, 0L, 0L, 0L), `2017-12` = c(0L, 
0L, 0L, 0L, 1L, 0L), `2018-01` = c(0L, 0L, 1L, 1L, 0L, 0L), `2018-02` = c(1L, 
0L, 0L, 0L, 0L, 0L), `2018-03` = c(0L, 0L, 0L, 0L, 0L, 0L), `2018-04` = c(0L, 
0L, 0L, 0L, 0L, 1L), Status = c("OK", "NOK", "OK", "NOK", "OK", 
"OK")), .Names = c("PN", "2017-10", "2017-11", "2017-12", 
"2018-01", "2018-02", "2018-03", "2018-04", "Status"), row.names = c(NA, 
-6L), class = c("tbl_df", "tbl", "data.frame"))

长话短说......让我得到上面输出的两个步骤是:

1 分析早期

mutate(n = parse_integer(str_replace_na(n, replacement = 0)))

2 稍后分析

mutate(
  Status = 
    ifelse(
      (apply(.[, 2:7], 1, sum) > 0) & 
        (.[, 8] > 0), 
      "NOK", 
      "OK"
      )
)

两位善良的堆栈战士@joran和@akrun告诉我,我“创建了一列字符矩阵”,这就是为什么我不断收到“排列_impl(.data,点)中的错误) :参数 1 属于不支持的矩阵类型” 错误。

用简单的英语来说,我做了什么?我是那种还不明白原子矢量和原子粒子之间区别的人。您能回答得简洁明了吗?

或者你可以告诉我阅读R for Data Science中的XYZ章节或类似内容。我也会接受(也许在评论中)。

最佳答案

为了按照通常预期的方式运行,ifelse 需要一个逻辑 向量作为第一个参数。

您在此处提供的内容是(将 . 替换为 df):

(apply(df[, 2:7], 1, sum) > 0) & (df[, 8] > 0)
# which btw we can rewrite more clearly as:
# rowSums(df[2:7]) > 0 & df[,8] >0

#      2018-04
# [1,]   FALSE
# [2,]   FALSE
# [3,]   FALSE
# [4,]   FALSE
# [5,]   FALSE
# [6,]   FALSE

常规 data.frame 不会发生这种情况,因为 df[,8] 会转换为向量。

阅读?Extract关于drop参数,tibbles的行为有点像data.framesdrop = FALSE

head(iris[,1])
# [1] 5.1 4.9 4.7 4.6 5.0 5.4

head(iris[,1,drop=FALSE])
#   Sepal.Length
# 1          5.1
# 2          4.9
# 3          4.7
# 4          4.6
# 5          5.0
# 6          5.4

head(as_tibble(iris)[,1])
# # A tibble: 6 x 1
#   Sepal.Length
# <dbl>
# 1          5.1
# 2          4.9
# 3          4.7
# 4          4.6
# 5          5.0
# 6          5.4

我们不需要了解它如何转换为错误的结果,让我们设法纠正输入。

为此,您可以使用 df[[8]] 而不是 df[,8],它始终是一个向量。

df %>% mutate(
  Status = 
    ifelse(
      rowSums(.[, 2:7]) > 0 & .[[8]] > 0, 
      "NOK", 
      "OK"
    )
) %>% str

# Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 6 obs. of  9 variables:
# $ PN     : chr  "41681" "16588" "34881" "36917" ...
# $ 2017-10: int  0 0 0 0 0 0
# $ 2017-11: int  0 1 0 0 0 0
# $ 2017-12: int  0 0 0 0 1 0
# $ 2018-01: int  0 0 1 1 0 0
# $ 2018-02: int  1 0 0 0 0 0
# $ 2018-03: int  0 0 0 0 0 0
# $ 2018-04: int  0 0 0 0 0 1
# $ Status : chr  "OK" "OK" "OK" "OK" ...

现在结构不再有问题了。

另一种方法是使用 if_else (来自 dplyr 包),它只向您的解决方案添加一个下划线字符,但不会教会我们太多:)代替ifelse。它在内部进行了神奇的转换,就像您在注释中使用 as.vector 所做的那样。

采用您的原始代码并仅添加神奇的 _:

df %>% mutate(
  Status = 
    if_else(
      (apply(.[, 2:7], 1, sum) > 0) & 
        (.[, 8] > 0), 
      "NOK", 
      "OK"
    )
) %>% str
# Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 6 obs. of  9 variables:
# $ PN     : chr  "41681" "16588" "34881" "36917" ...
# $ 2017-10: int  0 0 0 0 0 0
# $ 2017-11: int  0 1 0 0 0 0
# $ 2017-12: int  0 0 0 0 1 0
# $ 2018-01: int  0 0 1 1 0 0
# $ 2018-02: int  1 0 0 0 0 0
# $ 2018-03: int  0 0 0 0 0 0
# $ 2018-04: int  0 0 0 0 0 1
# $ Status : chr  "OK" "OK" "OK" "OK" ...

错误说明

df %>% mutate(
  Status = 
    ifelse(
      (apply(.[, 2:7], 1, sum) > 0) & 
        (.[, 8] > 0), 
      "NOK", 
      "OK"
    )
) %>% str

# Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 6 obs. of  9 variables:
# $ PN     : chr  "41681" "16588" "34881" "36917" ...
# $ 2017-10: int  0 0 0 0 0 0
# $ 2017-11: int  0 1 0 0 0 0
# $ 2017-12: int  0 0 0 0 1 0
# $ 2018-01: int  0 0 1 1 0 0
# $ 2018-02: int  1 0 0 0 0 0
# $ 2018-03: int  0 0 0 0 0 0
# $ 2018-04: int  0 0 0 0 0 1
# $ Status : chr [1:6, 1] "OK" "OK" "OK" "OK" ...
# ..- attr(*, "dimnames")=List of 2
# .. ..$ : NULL
# .. ..$ : chr "2018-04"

显示Status是一个6行1列的字符矩阵。 arrange 不喜欢这样。

为什么你会得到一个字符矩阵?

  • df[, 8] 是一个小标题
  • 所以 df[, 8] > 0 是一个矩阵
  • 所以 (apply(.[, 2:7], 1, sum) > 0) & (.[, 8] > 0) 是一个矩阵

?ifelse 表示输出值:

A vector of the same length and attributes (including dimensions and "class") as test

因此,Status 将是一个矩阵,一切最终都有意义;)。

另请参阅 ?dplyr::if_else 了解更多信息。

关于R - 创建一列字符矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50632685/

相关文章:

r - pdBlocked 的语法用于指定混合效应模型 nlme 中的协方差矩阵

r - 使用bca非参数方法进行引导的最小数量是多少

r - 如何改变过滤后的行(使用 dplyr 或 if/else)

r - 在 dplyr 中构建动态行数的总和

r - 如何使用mutate在R中正确格式化日期时间列?

r - 如何找到采样值的索引?

r - 并行计算 15 行(通过矢量化)并用它们创建 df

r - 将 data.frames 列表的列表转换为 R 中的单个 data.frame

r - 按组对 df 进行子集化,遍历散点图

r - 使用 r 从 s3 读取 zip 文件