【问题标题】:R: median of specific value rowsR:特定值行的中位数
【发布时间】:2016-12-05 13:07:27
【问题描述】:

我需要根据另一列 (SEQ) 获取行的中值。让我根据示例数据为您解释一下:

data <- structure(list(DATUM = structure(c(1335558400, 1335558400, 1335558400, 
                                           1335558400, 1335562429, 1335562429, 1335562429, 1335562429, 1335562429, 
                                           1335562429, 1335562429, 1335562429, 1335562429, 1335562429, 1335562429, 
                                           1335567274, 1335567274, 1335567274, 1335567274, 1335567274, 1335567274, 
                                           1335567274, 1335567274, 1335567274, 1335567274, 1335567274, 1335681543, 
                                           1335681543, 1335681543, 1335681543), class = c("POSIXct", "POSIXt"
                                           )), CHGNR = c(200028, 200028, 200028, 200028, 200029, 200029, 
                                                         200029, 200029, 200029, 200029, 200029, 200029, 200029, 200029, 
                                                         200029, 200029, 200029, 200029, 200029, 200029, 200029, 200029, 
                                                         200029, 200029, 200029, 200029, 200057, 200057, 200057, 200057
                                           ), SEQ = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
                                                      2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 1L, 2L, 2L, 
                                                      2L
                                          ), PROBE = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 
                                                       2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 1, 2, 2, 
                                                     2
                                          ), METHODE = c("a", "a", "b", "b", "a", "a", "a", "a", "a", "b", "b", "b", "b", "a", "a",
                                                         "a", "a", "a", "a", "b", "b", "b", "b", "b", "b", "a", "a", "a", "b", "b"
                                          ),MITTELWERT = c(2.5,1.67, 0, 0, 0.5, 0.333333333333333, 0.5, 0, 0, 0, 0, 
                                                             0, 5, 0, 0.833333333333333, 0, 0, 0, 0, 0, 0.5, 1, 0, 0, 
                                                             0, 0.5, 0.666666666666667,1, 0, 0)
                       ), .Names = c("DATUM", "CHGNR", "SEQ","PROBE","METHODE", "MITTELWERT"), 
                  row.names = c(NA,30L), class = "data.frame")

所以数据看起来像这样:

                 DATUM  CHGNR SEQ PROBE METHODE MITTELWERT
1  2012-04-27 22:26:40 200028   1     1       a  2.5000000
2  2012-04-27 22:26:40 200028   1     1       a  1.6700000
3  2012-04-27 22:26:40 200028   1     1       b  0.0000000
4  2012-04-27 22:26:40 200028   1     1       b  0.0000000
5  2012-04-27 23:33:49 200029   1     1       a  0.5000000
6  2012-04-27 23:33:49 200029   1     1       a  0.3333333
7  2012-04-27 23:33:49 200029   2     2       a  0.5000000
8  2012-04-27 23:33:49 200029   2     2       a  0.0000000
9  2012-04-27 23:33:49 200029   2     2       a  0.0000000
10 2012-04-27 23:33:49 200029   2     2       b  0.0000000
11 2012-04-27 23:33:49 200029   2     2       b  0.0000000
12 2012-04-27 23:33:49 200029   2     2       b  0.0000000
13 2012-04-27 23:33:49 200029   2     2       b  5.0000000
14 2012-04-27 23:33:49 200029   2     2       a  0.0000000
15 2012-04-27 23:33:49 200029   2     2       a  0.8333333
16 2012-04-28 00:54:34 200029   3     2       a  0.0000000
17 2012-04-28 00:54:34 200029   3     2       a  0.0000000
18 2012-04-28 00:54:34 200029   3     2       a  0.0000000
19 2012-04-28 00:54:34 200029   3     2       a  0.0000000
20 2012-04-28 00:54:34 200029   3     2       b  0.0000000
21 2012-04-28 00:54:34 200029   3     3       b  0.5000000
22 2012-04-28 00:54:34 200029   3     3       b  1.0000000
23 2012-04-28 00:54:34 200029   3     3       b  0.0000000
24 2012-04-28 00:54:34 200029   3     3       b  0.0000000
25 2012-04-28 00:54:34 200029   3     3       b  0.0000000
26 2012-04-28 00:54:34 200029   3     3       a  0.5000000
27 2012-04-29 08:39:03 200057   1     1       a  0.6666667
28 2012-04-29 08:39:03 200057   2     2       a  1.0000000
29 2012-04-29 08:39:03 200057   2     2       b  0.0000000
30 2012-04-29 08:39:03 200057   2     2       b  0.0000000

我想为每个唯一的CHGNRMETHODE 获得一个 新行 列的中位数为 MITTELWERT 并且仅适用于 SEQ > 1 (+ DATUMPROBE 列的第一个值)。因此,在此示例数据中,它看起来像这样:

                 DATUM  CHGNR SEQ PROBE METHODE MITTELWERT
1  2012-04-27 22:26:40 200028   1     1       a  2.5000000
2  2012-04-27 22:26:40 200028   1     1       a  1.6700000
3  2012-04-27 22:26:40 200028   1     1       b  0.0000000
4  2012-04-27 22:26:40 200028   1     1       b  0.0000000
5  2012-04-27 23:33:49 200029   1     1       a  0.5000000
6  2012-04-27 23:33:49 200029   1     1       a  0.3333333
7  2012-04-27 23:33:49 200029   2     2       a  0.5000000
8  2012-04-27 23:33:49 200029   2     2       a  0.0000000
9  2012-04-27 23:33:49 200029   2     2       a  0.0000000
10 2012-04-27 23:33:49 200029   2     2       b  0.0000000
11 2012-04-27 23:33:49 200029   2     2       b  0.0000000
12 2012-04-27 23:33:49 200029   2     2       b  0.0000000
13 2012-04-27 23:33:49 200029   2     2       b  5.0000000
14 2012-04-27 23:33:49 200029   2     2       a  0.0000000
15 2012-04-27 23:33:49 200029   2     2       a  0.8333333
16 2012-04-28 00:54:34 200029   3     2       a  0.0000000
17 2012-04-28 00:54:34 200029   3     2       a  0.0000000
18 2012-04-28 00:54:34 200029   3     2       a  0.0000000
19 2012-04-28 00:54:34 200029   3     2       a  0.0000000
20 2012-04-28 00:54:34 200029   3     2       b  0.0000000
21 2012-04-28 00:54:34 200029   3     3       b  0.5000000
22 2012-04-28 00:54:34 200029   3     3       b  1.0000000
23 2012-04-28 00:54:34 200029   3     3       b  0.0000000
24 2012-04-28 00:54:34 200029   3     3       b  0.0000000
25 2012-04-28 00:54:34 200029   3     3       b  0.0000000
26 2012-04-28 00:54:34 200029   3     3       a  0.5000000
27 2012-04-27 23:33:49 200029   >1    2       a  0.0000000 #new calculated row with median value for unique CHGNR and METHODE "a"
28 2012-04-27 23:33:49 200029   >1    2       b  0.0000000 #new calculated row with median value for unique CHGNR and METHODE "b"
...

感谢您的任何提示!

【问题讨论】:

  • 对于您提供的测试数据,这些中位数值是否正确?因为我看到 SEQ==a 和 SEQ==b 的 CHGNR==200029 的中位数(MITTELWERT)为零
  • 它应该是 CHGNR == 200029 和 SEQ > 1 和 METHODE == a /或 METHODE == b 的中值(MITTELWERT),但是是的,你是对的,我的错,我计算错了这个例子
  • 不要成为一个坚持者,但对于 medianmean 不同的数据集,您使用 Mittelwert=median() 是错误的——这个词意味着mean()
  • 嗨,德克,不是真的。整列实际上是测试方法(prufmethode)的平均值。中值用于汇总 seq >1 的平均值。

标签: r


【解决方案1】:

这可以通过library(data.table) 来实现。

library(data.table)    
# Create data here ----      
data <- data.table(data) # Converts to data set

crunchedData <- data[SEQ > 1,
               j = .(SEQ = ">1",MITTELWERT = median(MITTELWERT) ),
              by = .(CHGNR,METHODE)]

从这里您可以使用DATUMPROBE 的任意值将rbind crunchedData 转换为data

如果您不熟悉 data.table,第一个参数 (i) 采用按行划分子集的逻辑(类似于数据框)。 j 填充了按列操作(其中每一列都可以通过其列名来引用),by(或k,如果您愿意)定义了用于对行进行分组的组。

【讨论】:

  • 这是一个非常有趣的解决方案,效果很好!我不熟悉 data.table 包,因此使用 dplyr 的解决方案对我来说是正确的。无论如何谢谢!
  • 加入 tidyverse 似乎意味着不惜一切代价接受其解决方案。
【解决方案2】:

您可以使用以下方法计算组中位数:

library(sqldf)
df1=sqldf("select DATUM,CHGNR,SEQ,PROBE,METHODE, median(MITTELWERT) as MITTELWERT from df where SEQ>1 group by CHGNR,METHODE")

然后您可以对数据框进行进一步修改,然后执行rbind

tail(rbind(df,df1))

               DATUM  CHGNR SEQ PROBE METHODE MITTELWERT
29 2012-04-29 12:09:03 200057   2     2       b          0
30 2012-04-29 12:09:03 200057   2     2       b          0
31 2012-04-28 04:24:34 200029   3     3       a          0
32 2012-04-28 04:24:34 200029   3     3       b          0
33 2012-04-29 12:09:03 200057   2     2       a          1
34 2012-04-29 12:09:03 200057   2     2       b          0

【讨论】:

    【解决方案3】:

    你可以使用dplyr:

    library(dplyr)
    out <- data %>% group_by(CHGNR,METHODE) %>% 
                    summarise(DATUM=DATUM[1],PROBE=PROBE[1],MITTELWERT=median(MITTELWERT[SEQ>1]),SEQ=">1") %>%
                    ungroup %>% filter(!is.na(MITTELWERT)) %>% 
                    select(DATUM,CHGNR,SEQ,PROBE,METHODE,MITTELWERT) #%>%
    

    我们group_by CHGNRMETHODE 将行拆分为每个 CHGNRMETHODE 的组。然后summarisemedian 计算中位数MITTELWERT。注意MITTELWERTSEQ&gt;1 的子集。在summarise 中,我们还总结了DATUMPROBE 及其第一个元素,我们将SEQ 设置为"&gt;1"。最后,我们ungroup,删除那些带有NA 的行并重新排列列以匹配原始data

    要将结果作为附加行添加到data,我们需要将SEQ 列更改为character。然后,我们可以使用bind_rows

    data$SEQ <- as.character(data$SEQ)
    out <- bind_rows(data,out)
                     DATUM  CHGNR SEQ PROBE METHODE MITTELWERT
    1  2012-04-27 16:26:40 200028   1     1       a  2.5000000
    2  2012-04-27 16:26:40 200028   1     1       a  1.6700000
    3  2012-04-27 16:26:40 200028   1     1       b  0.0000000
    4  2012-04-27 16:26:40 200028   1     1       b  0.0000000
    5  2012-04-27 17:33:49 200029   1     1       a  0.5000000
    6  2012-04-27 17:33:49 200029   1     1       a  0.3333333
    7  2012-04-27 17:33:49 200029   2     2       a  0.5000000
    8  2012-04-27 17:33:49 200029   2     2       a  0.0000000
    9  2012-04-27 17:33:49 200029   2     2       a  0.0000000
    10 2012-04-27 17:33:49 200029   2     2       b  0.0000000
    11 2012-04-27 17:33:49 200029   2     2       b  0.0000000
    12 2012-04-27 17:33:49 200029   2     2       b  0.0000000
    13 2012-04-27 17:33:49 200029   2     2       b  5.0000000
    14 2012-04-27 17:33:49 200029   2     2       a  0.0000000
    15 2012-04-27 17:33:49 200029   2     2       a  0.8333333
    16 2012-04-27 18:54:34 200029   3     2       a  0.0000000
    17 2012-04-27 18:54:34 200029   3     2       a  0.0000000
    18 2012-04-27 18:54:34 200029   3     2       a  0.0000000
    19 2012-04-27 18:54:34 200029   3     2       a  0.0000000
    20 2012-04-27 18:54:34 200029   3     2       b  0.0000000
    21 2012-04-27 18:54:34 200029   3     3       b  0.5000000
    22 2012-04-27 18:54:34 200029   3     3       b  1.0000000
    23 2012-04-27 18:54:34 200029   3     3       b  0.0000000
    24 2012-04-27 18:54:34 200029   3     3       b  0.0000000
    25 2012-04-27 18:54:34 200029   3     3       b  0.0000000
    26 2012-04-27 18:54:34 200029   3     3       a  0.5000000
    27 2012-04-29 02:39:03 200057   1     1       a  0.6666667
    28 2012-04-29 02:39:03 200057   2     2       a  1.0000000
    29 2012-04-29 02:39:03 200057   2     2       b  0.0000000
    30 2012-04-29 02:39:03 200057   2     2       b  0.0000000
    31 2012-04-27 17:33:49 200029  >1     1       a  0.0000000
    32 2012-04-27 17:33:49 200029  >1     2       b  0.0000000
    33 2012-04-29 02:39:03 200057  >1     1       a  1.0000000
    34 2012-04-29 02:39:03 200057  >1     2       b  0.0000000
    

    【讨论】:

    • 不错的解决方案!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-08
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 2018-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多