【问题标题】:Working with data & basic R programming使用数据和基本的 R 编程
【发布时间】:2017-06-21 19:22:29
【问题描述】:

我是 R(和 stackoverflow)的新手,我有一点问题(我认为)这是一件很容易做到的事情。

基本上我有一些数据,例如:

ID | Data
----------
1 | 20
----------
2 | 30
----------
3 | 25
----------
4 | 26
----------
5 | 88
----------
6 | 65
----------
7 | 70
----------
8 | 30
----------
9 | 15
----------
10| 22
----------

我想做的是:

  1. 进行前 3 次观察
  2. 计算这 3 个观察值的平均值
  3. 用自己的 ID 将其保存到另一个矩阵或数据框中
  4. 并继续其他 3 个观察结果。

因此,如果我有 15 个观察结果,在此示例中我将仅以 5 个结束。

谢谢!

【问题讨论】:

  • 欢迎使用 R 和 StackOverflow!如果您提供了一些您已经尝试过的示例,您会发现人们更愿意帮助您回答问题。那么,考虑到这一点,您对如何解决这些问题的初步想法是什么?最好在问题中提供答案,而不是在此处的 cmets 中。
  • 感谢@brittenb 的建议

标签: r average


【解决方案1】:

我们使用%/% 创建分组变量并使用base R 中的aggregate 来获取“数据”列的mean

df1$grp <- (seq_len(nrow(df1))-1) %/%3 + 1
aggregate(Data~grp, df1, FUN = mean)
#  grp     Data
#1   1 25.00000
#2   2 59.66667
#3   3 38.33333
#4   4 22.00000

%/% 表示整数除法。例如,如果我们对 10 的序列使用整数除法

(1:10-1) %/% 3 + 1
#[1] 1 1 1 2 2 2 3 3 3 4

注意最后加1是为了让组从1开始而不是0开始,但这只是一种选择

【讨论】:

  • OP 是 R 的新手。也许可以尝试解释一些您正在使用的东西,例如 %/% 和公式符号。
【解决方案2】:

使用data.table 的类似解决方案是:

library(data.table)
setDT(df)[, mean(Data), by = .(((seq_len(nrow(df))-1) %/% 3) + 1)]

#   seq_len       V1
#1:       1 25.00000
#2:       2 59.66667
#3:       3 38.33333
#4:       4 22.00000

这很好,因为data.tableby 采用表达式,因此您无需创建新变量。 计算组的功劳归于 akrun


一点背景:

来自data.table 小插图:

data.table 继承自 data.frame。它提供快速且高效的内存:文件读取器和写入器、聚合、更新、等值、非等值、滚动、范围和间隔连接,语法简短灵活,可加快开发速度。

data.table 的语法与data.frames 可能有很大不同。在这种情况下,我们指定要执行的计算(mean(Data)),然后我们还告诉data.table 分组依据 - 在这种情况下,表达式((seq_len(nrow(df))-1) %/% 3) + 1,其计算结果为一个数字向量,该向量由每 4 个元素 1 个:

((seq_len(nrow(df))-1) %/% 3) + 1
 [1] 1 1 1 2 2 2 3 3 3 4

然后返回您在上面看到的输出。

数据:

df <- structure(list(ID = 1:10, Data = c(20L, 30L, 25L, 26L, 88L, 65L, 
       70L, 30L, 15L, 22L)), .Names = c("ID", "Data"), row.names = c(NA, 
       -10L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x00000000063e0788>)

【讨论】:

    【解决方案3】:

    一种方法是首先创建一个分组变量。这个变量将允许我们将数据集split 放入我们的组中,然后找到平均值。然后我们可以将手段和它们的 id 组合成一个新的数据框。

    让我们从分组变量开始。我们将利用模数 %% 来做到这一点。

    set.seed(9025)
    df = data.frame(id=1:10, values=sample(1:100, 10, FALSE))
    df$group = df$id - (df$id %% -3)
    
    df
       id values group
    1   1     85     3
    2   2      2     3
    3   3     93     3
    4   4     47     6
    5   5     90     6
    6   6      1     6
    7   7     27     9
    8   8     57     9
    9   9     81     9
    10 10      3    12
    

    现在我们可以通过我们的组变量split

    dl = split(df, df$group)
    dl
    $`3`
      id values group
    1  1     85     3
    2  2      2     3
    3  3     93     3
    
    $`6`
      id values group
    4  4     47     6
    5  5     90     6
    6  6      1     6
    
    $`9`
      id values group
    7  7     27     9
    8  8     57     9
    9  9     81     9
    
    $`12`
       id values group
    10 10      3    12
    

    split 只是通过我们提供给它的变量来分解数据框。所以第一个数据帧只是df 的子集,其中df$group 等于3。df$group 的实际值无关紧要,因为我们不会使用它。我们只需要确保一次获得三行。

    接下来,我们只是遍历list,然后计算平均值

    means = unname(sapply(dl, function(x) mean(x$values), simplify=TRUE))
    means
    60 46 55  3
    

    最后,我们只是把它变成一个新的数据框。

    n = length(means)
    new_df = data.frame(id=1:n, mean=means)
    new_df
      id mean
    1  1   60
    2  2   46
    3  3   55
    4  4    3
    

    总的来说,算法如下所示:

    df$group = df$id - (df$id %% -3)
    dl = split(df, df$group)
    means = unname(sapply(dl, function(x) means(x$values), simplify=TRUE)
    n = length(means)
    new_df = data.frame(id=1:n, mean=means)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-08
      • 1970-01-01
      • 2021-10-14
      相关资源
      最近更新 更多