我有一个数据框,看起来像这样。
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,但也不能成功。
谢谢你的帮助
这里有一个方法 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
这里是一个 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)