【问题标题】:Average score in a row vector using only certain values (split half) in R仅使用 R 中的某些值(拆分一半)的行向量中的平均分数
【发布时间】:2021-06-09 17:57:59
【问题描述】:

抱歉,如果这已在其他地方得到解答,我确实看过,但找不到可以复制的示例。

如果我有以下称为 DF 的数据框,其中 1-14 是得分为 1、0 或 3 的项目

Id        Date         1   2   3   4   5   6   7   8   9   10   11   12   13   14
             
1        01/01/01      1   0   3   3   1   0   1   3   1   0    3    0    1    1  
2        01/02/01      0   3   1   1   0   1   1   1   1   3    1    1    1    3

如何创建一个列,对每个 ID 的项目 1-7 进行平均,不包括 3 或 0 分(所以只有 1 个值),然后为 8-14 创建另一个列?

所以我会这样:

Id        Date         1   2   3   4   5   6   7   8   9   10   11   12   13   14   av1-7   av8-14
             
1        01/01/01      1   0   3   3   1   0   1   3   1   0    3    0    1    1    0.428   0.428
2        01/02/01      0   3   1   1   0   1   1   1   1   3    1    1    1    3    0.57    0.71

如果有人可以提供帮助,将不胜感激。

【问题讨论】:

  • A.) 如果您提供可重现的示例,我们会更容易提供帮助。这避免了我们粘贴​​和复制内容以及摆弄您的数据集。 dput() 是一个神奇的功能。但是请阅读最少的可重现示例。 B.) 你已经制定了你的编程例程。尝试编码。如果您将数据转换为垂直格式,您可以通过 df$new_col <- my operation 或使用 `mutate(newcol = my operation) 轻松创建一个新列。您可以构建您想要的条件,或者只是将 1 个值相加,然后取平均值。

标签: r dataframe row average


【解决方案1】:

这是dplyr 的一种方法:

data %>%
  rowwise() %>%
  mutate(`av1-7` = mean(recode(c_across(`1`:`7`),`1`= 1, .default = 0)),
         `av8-14` = mean(recode(c_across(`8`:`14`),`1`= 1, .default = 0)))
# Rowwise: 
     Id Date       `1`   `2`   `3`   `4`   `5`   `6`   `7`   `8`   `9`  `10`  `11`  `12`  `13`  `14` `av1-7` `av8-14`
  <int> <chr>    <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>   <dbl>    <dbl>
1     1 01/01/01     1     0     3     3     1     0     1     3     1     0     3     0     1     1   0.429    0.429
2     2 01/02/01     0     3     1     1     0     1     1     1     1     3     1     1     1     3   0.571    0.714

一般来说,将列名作为数字或包含- 并不是一个好主意。所以最好重命名这些列。

数据:

data <- structure(list(Id = 1:2, Date = c("01/01/01", "01/02/01"), `1` = 1:0, 
    `2` = c(0L, 3L), `3` = c(3L, 1L), `4` = c(3L, 1L), `5` = 1:0, 
    `6` = 0:1, `7` = c(1L, 1L), `8` = c(3L, 1L), `9` = c(1L, 
    1L), `10` = c(0L, 3L), `11` = c(3L, 1L), `12` = 0:1, `13` = c(1L, 
    1L), `14` = c(1L, 3L)), class = "data.frame", row.names = c(NA, 
-2L))

【讨论】:

  • 如果我的理解正确,您的答案会通过重新编码 1:7 中的值来创建列 av1-7。代码如何只选择 1 的值?是通过1= 1, .default = 0 部分吗?
  • 是的,你是对的。 1 被重新编码为 1,其他所有内容都为 0。
  • 我添加了 data% 以将它们添加为 DF 中的新列。它说不要在 cmets 中表示感谢,但我非常感谢您的帮助。
  • 在代码的第二部分(重命名)中,1 = 1:0, 2 = c(0L, 3L), 3 = c(3L, 1L) 是什么正在做?我知道它正在重命名列,但是 1、2 和 3 的三个操作有什么区别?
  • 好的,我的意思是在你重命名列的部分,1 = 1:0, 2 = c(0L, 3L), 3 = c(3L, 1L) 是什么意思?
【解决方案2】:

我们可以使用rowMeans by selecting 感兴趣的列

df1 <- df1 %>%
    mutate(across(`1`:`14`, ~ replace(., . != 1, 0))) %>%
   transmute(`av1-7` = rowMeans(select(cur_data(), `1`:`7`), na.rm = TRUE),
           `av8-14`= rowMeans(select(cur_data(), `8`:`14`), na.rm = TRUE)) %>%
    bind_cols(df1, .) %>%
    as_tibble

-输出

df1
# A tibble: 2 x 18
     Id Date       `1`   `2`   `3`   `4`   `5`   `6`   `7`   `8`   `9`  `10`  `11`  `12`  `13`  `14` `av1-7` `av8-14`
  <int> <chr>    <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>   <dbl>    <dbl>
1     1 01/01/01     1     0     3     3     1     0     1     3     1     0     3     0     1     1   0.429    0.429
2     2 01/02/01     0     3     1     1     0     1     1     1     1     3     1     1     1     3   0.571    0.714

数据

df1 <- structure(list(Id = 1:2, Date = c("01/01/01", "01/02/01"), `1` = 1:0, 
    `2` = c(0L, 3L), `3` = c(3L, 1L), `4` = c(3L, 1L), `5` = 1:0, 
    `6` = 0:1, `7` = c(1L, 1L), `8` = c(3L, 1L), `9` = c(1L, 
    1L), `10` = c(0L, 3L), `11` = c(3L, 1L), `12` = 0:1, `13` = c(1L, 
    1L), `14` = c(1L, 3L)), class = "data.frame", row.names = c(NA, 
-2L))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    • 2016-08-01
    • 1970-01-01
    • 2020-08-18
    • 2016-12-09
    • 1970-01-01
    相关资源
    最近更新 更多