使用自写函数时tibbles和dataframes的区别

Difference between tibbles and data frames when using selfwritten function

我试过的是:

identical_length_values <- function(x){
  nchar(x[,1]) == nchar(x[,2])
}

a <- "abc"
b <- "cba"
c <- "abc"
d <- "cbaa"
df1 <- data.frame(a, b)
df2 <- data.frame(c, d)
list1 <- list(df1, df2)

names(which(sapply(list1, identical_length_values)))

这给了我想要的东西:

[1] "hello"

如果这些数据帧是 tibbles,我得到以下信息:

df1 <- as_tibble(data.frame(a, b))
df2 <- as_tibble(data.frame(c, d))
list1 <- list(hello = df1, bye = df2)

names(which(sapply(list1, identical_length_values)))

[1] "hello.a"

为什么我的函数在这里添加第一列的列名,用点分隔?我想不出我想要的场景。

主要区别在于默认情况下数据帧如何处理单列数据帧的子集与 tibbles。

当您仅使用一列对数据框进行子集化时,它会删除它的维度并返回一个向量。

df1 <- data.frame(a, b)
df1[, 1]
#[1] "abc"

class(df1[, 1])
#[1] "character"

当您将 tibble 与一列子集时,您会得到一个 tibble。

df1 <- as_tibble(data.frame(a, b))
df1[, 1]
# A tibble: 1 x 1
 # a    
 # <chr>
#1 abc  
class(df1[, 1])
#[1] "tbl_df"     "tbl"        "data.frame"

因此,对于数据帧,数据中没有要附加到最终输出中的列名称,因此您只能返回列表名称。

df1 <- data.frame(a, b)
df2 <- data.frame(c, d)
list1 <- list(hello = df1, bye = df2)
sapply(list1, identical_length_values)
#hello   bye 
# TRUE FALSE 

但是,对于 tibbles,列名仍然存在,因此它会附加到结果中。

df1 <- as_tibble(data.frame(a, b))
df2 <- as_tibble(data.frame(c, d))
list1 <- list(hello = df1, bye = df2)
sapply(list1, identical_length_values)
#hello.a   bye.c 
#   TRUE   FALSE 

如果您使用 [[ 而不是 [,它总是 return 返回向量,您将不会遇到这个问题。

identical_length_values <- function(x){
  nchar(x[[1]]) == nchar(x[[2]])
}