R语言 如何获取特定列的中位数

bpsygsoo  于 2023-04-03  发布在  其他
关注(0)|答案(4)|浏览(275)

我有这样一个数据

df<-structure(list(T = c(36034L, 63763L, 51432L, 65100L, 61444L, 
71012L, 266610L, 389787L, 47659L, 63156L, 84593L, 84331L), T.1 = c(45632L, 
66505L, 60360L, 36685L, 107551L, 53360L, 323952L, 344944L, 69601L, 
51268L, 130665L, 59704L), T.2 = c(59025L, 52837L, 68571L, 35788L, 
75262L, 66601L, 424683L, 340948L, 79487L, 42809L, 95607L, 81739L
), BG = c(74767L, 48210L, 70972L, 67705L, 85576L, 89265L, 393380L, 
306633L, 77816L, 73611L, 106317L, 116890L), BG.1 = c(50846L, 
37970L, 63896L, 78296L, 81216L, 62308L, 62613L, 21770L, 80955L, 
88832L, 97586L, 68345L), BG.2 = c(26688L, 27830L, 17010L, 54074L, 
26727L, 31109L, 24448L, 38701L, 17378L, 46327L, 25324L, 25325L
), TR = c(16498L, 26604L, 41201L, 38417L, 43709L, 33217L, 69943L, 
80638L, 37444L, 31701L, 46781L, 31152L), TR.1 = c(16272L, 24485L, 
14546L, 74756L, 28193L, 770L, 72238L, 78418L, 9161L, 48618L, 
26466L, 1078L), TR.2 = c(20612L, 713L, 18114L, 57872L, 25684L, 
27985L, 73618L, 1770L, 11953L, 33347L, 25824L, 25860L)), row.names = c("A", 
"B", "C", "D", "E", "F", "A_Mo1", "B_Mo1", "C_Mo1", "D_Mo1", 
"E_Mo1", "F_Mo1"), class = "data.frame")

我试图得到中位数为每一行的基础上,每3列。我已经尝试了很多事情,但没有成功。
第一途径

apply(df, 2, FUN = median)

另一种方式

dataused <- c("1:3","4:6","7:9")
medians <- sapply(dataused,function(y)
  c(by(df[,eval(parse(text=y))],median(unlist(x)))))
bgtovc5b

bgtovc5b1#

一个选项是rowMedians

library(matrixStats)
sapply(list(as.matrix(df[1:3]), as.matrix(df[4:6]), as.matrix(df[7:9])), rowMedians)

或仅使用base R

nm1 <-  sub("\\.\\d+$", "", names(df))
df[paste0(unique(nm1), "_median")] <- sapply(split.default(df, nm1),
            function(x) apply(x, MARGIN = 1, FUN = median))

或基于列名模式的split

library(stringr)
library(dplyr)
library(purrr)
df %>% 
   split.default(str_remove(names(.), "\\.\\d+$")) %>%
    map_df(~ as.matrix(.x) %>% 
                  rowMedians)
# A tibble: 12 x 3
#      BG      T    TR
#   <dbl>  <dbl> <dbl>
# 1 50846  45632 16498
# 2 37970  63763 24485
# 3 63896  60360 18114
# 4 67705  36685 57872
# 5 81216  75262 28193
# 6 62308  66601 27985
# 7 62613 323952 72238
# 8 38701 344944 78418
# 9 77816  69601 11953
#10 73611  51268 33347
#11 97586  95607 26466
#12 68345  81739 25860
uyto3xhc

uyto3xhc2#

您可以在base中使用apply系列函数来实现。

t(apply(df1, 1, tapply, gl(3, 3), median, na.rm = TRUE))

#>            1     2     3
#> A      45632 50846 16498
#> B      63763 37970 24485
#> C      60360 63896 18114
#> D      36685 67705 57872
#> E      75262 81216 28193
#> F      66601 62308 27985
#> A_Mo1 323952 62613 72238
#> B_Mo1 344944 38701 78418
#> C_Mo1  69601 77816 11953
#> D_Mo1  51268 73611 33347
#> E_Mo1  95607 97586 26466
#> F_Mo1  81739 68345 25860
ohtdti5x

ohtdti5x3#

您没有指定要计算哪些列的中位数。但是您可以使用applyMARGIN参数作为1,它按行执行操作。根据data.frame的大小,它可能会稍微低效。假设您想对前三列执行此操作:

cols <- c("T", "T.1", "T.2")

newCols <- paste0("median_", paste0(cols, collapse = "_"))

df[[newCols]] <- apply(df[, cols], MARGIN=1, FUN=median)

结果:

> df
           T    T.1    T.2     BG  BG.1  BG.2    TR  TR.1  TR.2 median_T_T.1_T.2
A      36034  45632  59025  74767 50846 26688 16498 16272 20612            45632
B      63763  66505  52837  48210 37970 27830 26604 24485   713            63763
C      51432  60360  68571  70972 63896 17010 41201 14546 18114            60360
D      65100  36685  35788  67705 78296 54074 38417 74756 57872            36685
E      61444 107551  75262  85576 81216 26727 43709 28193 25684            75262
F      71012  53360  66601  89265 62308 31109 33217   770 27985            66601
A_Mo1 266610 323952 424683 393380 62613 24448 69943 72238 73618           323952
B_Mo1 389787 344944 340948 306633 21770 38701 80638 78418  1770           344944
C_Mo1  47659  69601  79487  77816 80955 17378 37444  9161 11953            69601
D_Mo1  63156  51268  42809  73611 88832 46327 31701 48618 33347            51268
E_Mo1  84593 130665  95607 106317 97586 25324 46781 26466 25824            95607
F_Mo1  84331  59704  81739 116890 68345 25325 31152  1078 25860            81739

为了完整性,使用data.table

cols <- c("T", "T.1", "T.2")
newCols <- paste0("median_", paste0(cols, collapse = "_"))
df[, (newCols) := apply(.SD, 1, median), .SDcols=cols]
wn9m85ua

wn9m85ua4#

可以使用dplyr和rowwise()

df %>% rowwise() %>% mutate(T_median = median(T, T.1, T.2), BG_median = median(BG, BG.1,BG.2), TR_median = median(TR, TR.1, TR.2))


        T    T.1    T.2     BG  BG.1  BG.2    TR  TR.1  TR.2 T_median BG_median TR_median
    <int>  <int>  <int>  <int> <int> <int> <int> <int> <int>    <int>     <int>     <int>
 1  36034  45632  59025  74767 50846 26688 16498 16272 20612    36034     74767     16498
 2  63763  66505  52837  48210 37970 27830 26604 24485   713    63763     48210     26604
 3  51432  60360  68571  70972 63896 17010 41201 14546 18114    51432     70972     41201
 4  65100  36685  35788  67705 78296 54074 38417 74756 57872    65100     67705     38417
 5  61444 107551  75262  85576 81216 26727 43709 28193 25684    61444     85576     43709
 6  71012  53360  66601  89265 62308 31109 33217   770 27985    71012     89265     33217
 7 266610 323952 424683 393380 62613 24448 69943 72238 73618   266610    393380     69943
 8 389787 344944 340948 306633 21770 38701 80638 78418  1770   389787    306633     80638
 9  47659  69601  79487  77816 80955 17378 37444  9161 11953    47659     77816     37444
10  63156  51268  42809  73611 88832 46327 31701 48618 33347    63156     73611     31701
11  84593 130665  95607 106317 97586 25324 46781 26466 25824    84593    106317     46781
12  84331  59704  81739 116890 68345 25325 31152  1078 25860    84331    116890     31152

相关问题