如何分割数据框架,应用某些功能,并将其重新组合在一起?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (35)

我经常有一个包含数值变量和分类变量的数据框,我想根据分类变量拆分数值变量,执行一些操作,然后以数据框的形式将它们重新组合在一起。该操作取决于类别中数字向量的整个部分,并且有时会返回不同长度的向量。我知道如何以丑陋的方式做到这一点(见下面的例子),但它似乎是一个常见的操作,所以我想知道是否有一种我不知道的更简单的方法。我特别想知道是否有使用的解决方案tidyverse

这是我正在谈论的一个例子。

df = data.frame(y=1:10, g=rep(c("a", "b"), each=5))

假设我想为变量的每个级别将变量标准化为y0到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。如果我们将示例更改为数值向量的大小减小但大于1的操作,则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 with使用原始格式

data.frame(g=rep(trans_df$g, times=sapply(trans_df$y, length)),
           y=do.call(c, trans_df$y))

但我怎么能用tidyverse呢?

提问于
用户回答回答于

在R你可以这样做:

df$y <- ave(df$y,df$g, FUN = function(y) (y - min(y))/(max(y) - min(y)))
#       y g
# 1  0.00 a
# 2  0.25 a
# 3  0.50 a
# 4  0.75 a
# 5  1.00 a
# 6  0.00 b
# 7  0.25 b
# 8  0.50 b
# 9  0.75 b
# 10 1.00 b

或者这个效果相同:

split(df$y,df$g) <- tapply(df$y, df$g, function(y) (y - min(y))/(max(y) - min(y)))

如果你需要处理data.frame的其他变量,则会更灵活一些:

by_ <- by(df, df$g, function(x) transform(x, y = (y - min(y))/(max(y) - min(y))))
do.call(rbind, by_)
#         y g
# a.1  0.00 a
# a.2  0.25 a
# a.3  0.50 a
# a.4  0.75 a
# a.5  1.00 a
# b.6  0.00 b
# b.7  0.25 b
# b.8  0.50 b
# b.9  0.75 b
# b.10 1.00 b
用户回答回答于

这是经典的拆分 - 应用 - 组合方法。你按分类变量分组,将某些功能应用于各个组,然后重新组合在一起。在dplyr这由处理group_by

df <- data.frame(y=1:10, g=rep(c("a", "b"), each=5))

library(dplyr)
df %>%
  group_by(g) %>% 
  mutate(y2 = (y - min(y)) / (max(y) - min(y)))
#> # A tibble: 10 x 3
#> # Groups:   g [2]
#>        y g        y2
#>    <int> <fct> <dbl>
#>  1     1 a      0   
#>  2     2 a      0.25
#>  3     3 a      0.5 
#>  4     4 a      0.75
#>  5     5 a      1   
#>  6     6 b      0   
#>  7     7 b      0.25
#>  8     8 b      0.5 
#>  9     9 b      0.75
#> 10    10 b      1

df %>%
  group_by(g) %>% 
  top_n(-4, y)
#> # A tibble: 8 x 2
#> # Groups:   g [2]
#>       y g    
#>   <int> <fct>
#> 1     1 a    
#> 2     2 a    
#> 3     3 a    
#> 4     4 a    
#> 5     6 b    
#> 6     7 b    
#> 7     8 b    
#> 8     9 b

所属标签

可能回答问题的人

  • HKC

    红客学院 · 创始人 (已认证)

    26 粉丝7 提问5 回答
  • Dingda

    Dingda · 站长 (已认证)

    4 粉丝0 提问3 回答
  • 螃蟹居

    1 粉丝0 提问2 回答
  • 西风

    renzha.net · 站长 (已认证)

    9 粉丝1 提问2 回答

扫码关注云+社区

领取腾讯云代金券