通常,我有一个包含数字变量和分类变量的数据框,并且我想根据分类变量拆分数字变量,执行一些操作,然后以数据框的形式将其放回原处。该运算取决于类别中数值向量的整个部分,有时会返回不同长度的向量。我知道如何以丑陋的方式执行此操作(请参见下面的示例),但这似乎是一种常见的操作,所以我想知道是否有一种我不知道的简单方法。我特别想知道是否有使用的解决方案tidyverse
。
这是我正在谈论的示例。
df = data.frame(y=1:10, g=rep(c("a", "b"), each=5))
假设我想将分类变量的每个级别的变量标准化为y
0到1之间。这是执行此操作的一般方法:
do.call(
rbind,
lapply(unique(df$g),
function(level) {
y.current = df$y[df$g==level]
## perform some operation
y.new = (y.current-min(y.current))/
(max(y.current)-min(y.current))
return(data.frame(y=y.new,
g=level))
}
)
)
这需要大量的输入并且不是很可读。有没有更好的办法?
编辑:感谢您的伟大答案。我唯一仍然感兴趣的是使用tidyverse
。如果我们改变的例子的操作,其中的数值矢量的大小被减小,但大于一,则group_by
/ mutate
/summarize
组合不起作用。例如,假设我要删除每个组中的最大值。我可以
library(dplyr)
df = data.frame(y=1:10, g=rep(c("a", "b"), each=5))
trans_df = df %>%
group_by(g) %>%
do(y=.$y[-which.max(.$y)])
变换后的数据帧trans_df
具有每个级别只有一个观察值的分组变量,并且变换后的变量作为分组变量的每个级别的列表。我可以使用base R将它放在原始格式中
data.frame(g=rep(trans_df$g, times=sapply(trans_df$y, length)),
y=do.call(c, trans_df$y))
但是我该如何使用tidyverse
呢?
使用data.table:
library(data.table)
df=as.data.table(df)
df[,(y-min(y))/(max(y)-min(y)),by=g]
g V1
1: a 0.00
2: a 0.25
3: a 0.50
4: a 0.75
5: a 1.00
6: b 0.00
7: b 0.25
8: b 0.50
9: b 0.75
10: b 1.00
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句