【问题标题】:Inconsistency when cbind tibble and matrix in R在R中cbind tibble和matrix时不一致
【发布时间】:2021-03-01 01:11:43
【问题描述】:

不幸的是,当cbind 不同的 2 个特定对象:tibblesby_group()ed 和 matrix 时,我发现列名中有一个奇怪的不一致。我在这里写这篇文章是因为我会理解 cbind 操作和这两个对象的幕后情况。

考虑以下对象:

简单的小标题

library(tidyverse)

tbl <- tibble(tbl_name = seq(1,8))
# # A tibble: 8 x 1
# tbl_name
# <int>
# 1        1
# 2        2
# 3        3
# 4        4
# 5        5
# 6        6
# 7        7
# 8        8

简单的data.frame

df <- data.frame(df_name = seq(1,8))
df 

# df_name
# 1       1
# 2       2
# 3       3
# 4       4
# 5       5
# 6       6
# 7       7
# 8       8

简单matrix

mtx <- matrix(seq(1,8), nrow = 8)
colnames(mtx) <- "mtx_name"

# mtx_name
# [1,]        1
# [2,]        2
# [3,]        3
# [4,]        4
# [5,]        5
# [6,]        6
# [7,]        7
# [8,]        8

by_grouped tibble

tb2 <- tibble(tbl2_name = seq(1,8),
              tbl_group_by = c("a","b","b","c","d","d","d","d"))

tb2 <- tb2 %>%
  group_by(tbl_group_by) %>%
  mutate(N_by_group = n()) 
# A tibble: 8 x 3
# Groups:   tbl_group_by [4]
# tbl2_name tbl_group_by N_by_group
# <int> <chr>             <int>
# 1         1 a                     1
# 2         2 b                     2
# 3         3 b                     2
# 4         4 c                     1
# 5         5 d                     4
# 6         6 d                     4
# 7         7 d                     4
# 8         8 d                     4

cbind他们时:

>这行得通(又名:保持正确的名称)

# Comparison 

# tibble & data.frame: OK
cbind(tbl,df)
# tbl_name df_name
# 1        1       1
# 2        2       2
# 3        3       3
# 4        4       4
# 5        5       5
# 6        6       6
# 7        7       7
# 8        8       8


# matrix & data.frame: OK
cbind(mtx,df)

# mtx_name df_name
# 1        1       1
# 2        2       2
# 3        3       3
# 4        4       4
# 5        5       5
# 6        6       6
# 7        7       7
# 8        8       8

# tibble & matrix: OK
cbind(tbl,mtx)

# tbl_name mtx_name
# 1        1        1
# 2        2        2
# 3        3        3
# 4        4        4
# 5        5        5
# 6        6        6
# 7        7        7
# 8        8        8

这个工作(又名:破坏了matrix的colname)

# tibble(group_by()) & matrix: oops!!!!
cbind(tb2,mtx)

# New names:
#   * NA -> ...4
# # A tibble: 8 x 4
# # Groups:   tbl_group_by [4]
# tbl2_name tbl_group_by N_by_group ...4[,"mtx_name"]
# <int> <chr>             <int>             <int>
# 1         1 a                     1                 1
# 2         2 b                     2                 2
# 3         3 b                     2                 3
# 4         4 c                     1                 4
# 5         5 d                     4                 5
# 6         6 d                     4                 6
# 7         7 d                     4                 7
# 8         8 d                     4                 8

非常欢迎您对正在发生的事情或如何预防的任何直觉。提前谢谢你。

【问题讨论】:

    标签: r matrix dplyr tidyverse tibble


    【解决方案1】:

    我们可以使用ungroup 删除组属性,现在cbind 应该可以工作了

    library(dplyr)
    cbind(ungroup(tb2), mtx)
    

    -输出

    #    tbl2_name tbl_group_by N_by_group mtx_name
    #1         1            a          1        1
    #2         2            b          2        2
    #3         3            b          2        3
    #4         4            c          1        4
    #5         5            d          4        5
    #6         6            d          4        6
    #7         7            d          4        7
    #8         8            d          4        8
    

    或者专门使用cbind.data.frame,因为默认情况下它可能使用cbind.matrix

    cbind.data.frame(tb2, mtx)
    

    我们在创建'tb2'的时候,分组后,一定要ungroup,以免出现此类问题

    tb2 <- tb2 %>%
             group_by(tbl_group_by) %>%
             mutate(N_by_group = n())  %>%
             ungroup
    

    或者利用is_grouped_df判断数据是否分组,然后ungroup

    f1 <- function(dat) {
           if(dplyr::is_grouped_df(dat)) {
            dat <- ungroup(dat)
           }
           dat
       }
    
    cbind(f1(tb2), mtx)
    

    【讨论】:

    • 感谢您的回答@akrun。确实ungroup 解决了这个问题,但是......是否可以在创建时ungrouped tibble?因为,这可能更好,而不是开始猜测我的哪个小标题来自grouped,不是吗?
    • @ÁlvaroA.GutiérrezVargas 您可以使用as.data.frame 将所有小标题转换为data.frame,以便它删除组属性或在有group_by 操作时在管道末尾添加ungroup。更新了帖子
    • 谢谢@akrun!!!这正是我正在寻找的正是
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-24
    • 2018-05-08
    • 2022-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    相关资源
    最近更新 更多