【问题标题】:R: split a data.frame but keep classesR:拆分data.frame但保留类
【发布时间】:2021-05-10 08:12:06
【问题描述】:

我想将数据框拆分为数据框列表并保留变量的类。

# create sample data
df <- data.frame(
  id=c("1","2"),
  site_name = c("Zero Hedge", "Free Software Foundation"),
  site_url = c("https://www.zerohedge.com", "https://www.fsf.org")
)

# specify class for site_url 
class(df$site_url) <- "formula"

# split
dataframes <- split(df, df$id)

现在我想知道,为什么拆分的数据会改变类:

class(dataframes[[1]]$site_url)
[1] "character"

我的问题:

  1. 为什么会这样?
  2. 如何将数据框拆分为数据框列表并保留变量的类?

感谢您的帮助。

其他信息:

当我想用 R 和openxlsx自动编写指向 excel 文件的超链接时遇到了这个问题,@根据这篇非常有用的帖子:Openxlsx hyperlink output display in Excel

【问题讨论】:

  • R 并不真正支持公式向量。例如class(df$site_url[1]) 只返回字符。如果您尝试将它们放入向量中,R 会将其更改为列表class(c(a~b, c~b))。因此,仅将一类“公式”分配给向量就是问题所在。这实际上是不允许的,并且是真正导致错误的原因。 split 应该适用于适当的矢量类型。
  • @MrFlick 感谢您的宝贵意见。 stat.ethz.ch/R-manual/R-devel/library/base/html/class.html 告诉我,基本上任何值都可以用作一个类。我是否正确地认为只有此处列出的类 stat.ethz.ch/R-manual/R-devel/library/methods/html/… 实际上是“允许的”并且可以在数据处理期间工作?
  • 类名可以是任何你喜欢的字符串。 R 并没有真正的受保护的类名,也没有检查您分配的值是否实际有效。您可以运行x &lt;- 1:3;class(x) &lt;- "data.frame",但显然这没有意义,如果您尝试使用x 作为data.frame,您会遇到问题,因为它是一个向量。如果您希望您的对象行为正确,您应该只分配对基础对象类型有效的类名。如果你有一个向量,那么你应该只使用原子类类型。第二个链接专门针对 R 中的 S4 类,这是一个略有不同的主题。

标签: r dataframe class split


【解决方案1】:

我们可以设置属性

dataframes2 <- lapply(dataframes, function(x) {
      attributes(x$site_name) <- attributes(df$site_name)
     x}) 

该问题与split 或其方法无关。在这种情况下,它是split.data.frame。如果我们查看源代码,它是基于分组'f'的行序列拆分然后进行提取([

split.data.frame
function (x, f, drop = FALSE, ...) 
lapply(split(x = seq_len(nrow(x)), f = f, drop = drop, ...), 
    function(ind) x[ind, , drop = FALSE])

但是,split.data.table 保留了课程

split(as.data.table(df), df$id) %>% str
#List of 2
# $ 1:Classes ‘data.table’ and 'data.frame':    1 obs. of  3 variables:
# ..$ id       : chr "1"
# ..$ site_name: chr "Zero Hedge"
# ..$ site_url : 'formula' chr "https://www.zerohedge.com"
 # ..- attr(*, ".internal.selfref")=<externalptr> 
# $ 2:Classes ‘data.table’ and 'data.frame':    1 obs. of  3 variables:
#  ..$ id       : chr "2"
#  ..$ site_name: chr "Free Software Foundation"
#  ..$ site_url : 'formula' chr "https://www.fsf.org"

-使用提取的行数据检查原始数据的结构

str(df)
'data.frame':   2 obs. of  3 variables:
 $ id       : chr  "1" "2"
 $ site_name: chr  "Zero Hedge" "Free Software Foundation"
 $ site_url : 'formula' chr  "https://www.zerohedge.com" "https://www.fsf.org" str(df[1,]) # with one row selected
'data.frame':   1 obs. of  3 variables:
 $ id       : chr "1"
 $ site_name: chr "Zero Hedge"
 $ site_url : chr "https://www.zerohedge.com" # lost attribute
str(df[1:2,]) # with more than one row
'data.frame':   2 obs. of  3 variables:
 $ id       : chr  "1" "2"
 $ site_name: chr  "Zero Hedge" "Free Software Foundation"
 $ site_url : chr  "https://www.zerohedge.com" "https://www.fsf.org" # lost attribute

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多