如何在R中计算多列的ntiles?

问题描述 投票:0回答:1

我有一个数据框,看起来像这样。

ID age sex chem1 chem2 chem3 ... chem524
01 64  m   .06   6.8    .3        .2
02 57  f   .7    24.3    NA       .7
03 53  f   .4    2.9    .03       1.6
04 68  m   .7    37.8   .01       .01
05 73  m   1.2   1.4    2.8       3.6
06 49  f   .3    7.6    .3        2.9

我需要为每一种化学品做3个ntiles. 我知道如何一次只计算一种化学品,但我不想把它写出524次。

我希望将每种化学品的ntiles一起存储在一个新的数据框架中,这样我就可以在以后对它们做进一步的分析。

下面是我希望输出数据框的样子。

ID age sex chem1 chem2 chem3 ... chem524
01 64  m    1     2     2         1
02 57  f    2     3     NA        2
03 53  f    2     1     1         3
04 68  m    2     3     1         1
05 73  m    3     1     3         3
06 49  f    1     2     2         3

这是我试过的方法

df2 <- mutate_at(df, vars(chem1:chem524), ntile(top_air[4:528], 3))

这没有用,因为ntile似乎只能作用于一列。我也试过使用apply,但也不能成功。

谢谢你的帮助

r dataframe dplyr mutate
1个回答
1
投票

这里有一个方法 mutate_at:

library(dplyr)
df %>%
  mutate_at(vars(starts_with("chem")), .funs = list(~ntile(.,3)))
  ID age sex chem1 chem2 chem3 chem524
1  1  64   m     1     2     2       1
2  2  57   f     2     3    NA       2
3  3  53   f     2     1     1       2
4  4  68   m     3     3     1       1
5  5  73   m     3     1     3       3
6  6  49   f     1     2     2       3

适当地设定参数 .funs = 参数有点专业,但对于一个函数来说,只需提供一个以 ~. ~ 是一个匿名函数的简写,它有一个参数,我们可以使用 ..

你也可以为列表命名以获得新的列。

df %>%
  mutate_at(vars(starts_with("chem")), list(ntile = ~ntile(.,3)))

另一种方法是跳过所有的匿名函数,将额外的参数传递给 ntile 随着 ... 一部分 mutate_at:

df %>%
  mutate_at(vars(starts_with("chem")), ntile, 3)
  ID age sex chem1 chem2 chem3 chem524
1  1  64   m     1     2     2       1
2  2  57   f     2     3    NA       2
3  3  53   f     2     1     1       2
4  4  68   m     3     3     1       1
5  5  73   m     3     1     3       3
6  6  49   f     1     2     2       3

1
投票

这里是一个 data.table 的解决方案。

library(data.table)
df <- structure(list(ID = c(64L, 57L, 53L, 68L, 73L, 49L), 
                     age = c("m", "f", "f", "m", "m", "f"), 
                     sex = c(0.06, 0.7, 0.4, 0.7, 1.2, 0.3), 
                     chem1 = c(6.8, 24.3, 2.9, 37.8, 1.4, 7.6), 
                     chem2 = c(0.3, NA, 0.03, 0.01, 2.8, 0.3), 
                     chem3 = c(0.2, 0.7, 1.6, 0.01, 3.6, 2.9)), 
                class = "data.frame", 
                row.names = c("01", "02", "03", "04", "05", "06"))
dt <- data.table(df)
cols <- grep("^chem", colnames(dt), value = TRUE)
dt[, (cols) := lapply(.SD, dplyr::ntile, 3), .SDcols=cols][]
#>    ID age  sex chem1 chem2 chem3
#> 1: 64   m 0.06     2     2     1
#> 2: 57   f 0.70     3    NA     2
#> 3: 53   f 0.40     1     1     2
#> 4: 68   m 0.70     3     1     1
#> 5: 73   m 1.20     1     3     3
#> 6: 49   f 0.30     2     2     3

创立于2020-05-23 重读包 (v0.3.0)

© www.soinside.com 2019 - 2024. All rights reserved.