如何清除所有属性?

20

我想要从数据中删除所有属性并应用这个解决方案。然而,无论是one_entry()(原始函数)还是我自己的one_entry2()都不能正常工作,我不知道为什么。

one_entry2 <- function(x) {
  attr(x, "label") <- NULL
  attr(x, "labels") <- NULL
}

> lapply(df1, one_entry2)
$`id`
NULL

$V1
NULL

$V2
NULL

$V3
NULL

我们该怎么做?

数据:

df1 <- setNames(data.frame(matrix(1:12, 3, 4)), 
                c("id", paste0("V", 1:3)))
attr(df1$V1, "labels") <- LETTERS[1:4]
attr(df1$V1, "label") <- letters[1:4]
attr(df1$V2, "labels") <- LETTERS[1:4]
attr(df1$V2, "label") <- letters[1:4]
attr(df1$V3, "labels") <- LETTERS[1:4]
attr(df1$V3, "label") <- letters[1:4]

> str(df1)
'data.frame':   3 obs. of  4 variables:
 $ id: int  1 2 3
 $ V1: int  4 5 6
  ..- attr(*, "labels")= chr  "A" "B" "C" "D"
  ..- attr(*, "label")= chr  "a" "b" "c" "d"
 $ V2: int  7 8 9
  ..- attr(*, "labels")= chr  "A" "B" "C" "D"
  ..- attr(*, "label")= chr  "a" "b" "c" "d"
 $ V3: int  10 11 12
  ..- attr(*, "labels")= chr  "A" "B" "C" "D"
  ..- attr(*, "label")= chr  "a" "b" "c" "d"

2
如果有人需要从一个数字变量中删除所有属性,可以使用以下方法:as.numeric(a) - Tomas
as.numeric 也会删除名称。如果您想保留名称,特别是命名列表,可以尝试使用 as.list(unlist(a)) - passerby51
或者,如果你想移除向量中的其他属性但保留名称,你可以简单地使用c(a) - nisetama
或者,要删除其他属性但保留向量的名称,您可以简单地使用 c(a) - undefined
6个回答

29

要删除所有属性,可以这样做

df1[] <- lapply(df1, function(x) { attributes(x) <- NULL; x })
str(df1)
#'data.frame':  3 obs. of  4 variables:
# $ id: int  1 2 3
# $ V1: int  4 5 6
# $ V2: int  7 8 9
# $ V3: int  10 11 12

亲爱的Maurits,我可以问一下这里实际上df1[]是做什么的吗?我以前从未遇到过这种结构。提前感谢。 - Anoushiravan R
2
嗨@AnoushiravanR。与其让我笨拙地重新表述别人已经更好地说过的话,不如看看这里:(https://dev59.com/UmEi5IYBdhLWcg3wjs5j)。 - Maurits Evers
1
非常感谢您的回复和链接。您在这里做得非常好 :) 最好的祝愿。 - Anoushiravan R

8
简单概括一下@maurits-evers的回答:
df1[] <- lapply(df1, as.vector)
str(df1)
#'data.frame':  3 obs. of  4 variables:
# $ id: int  1 2 3
# $ V1: int  4 5 6
# $ V2: int  7 8 9
# $ V3: int  10 11 12

这篇原始回答由布莱恩·里普利教授在这篇R-Help帖子中提供。

tidyverse世界中:

df1 <- df1 %>% mutate(across(everything(), as.vector))

使用 data.table

library(data.table)
# Assuming
# setDT(df1) # or
# df1 <- as.data.table(df1)

df1 <- df1[, lapply(.SD, as.vector)] 

3
如果所有列的类型都相同(就像您的示例中那样),您可以执行以下操作:
df1[] = c(df1, recursive=TRUE)

2
以下是一种简单的解决方案(不会将日期类转换为数字):
df1 <- data.frame(df1)

我不知道为什么,但这确实是唯一对我有效的解决方案。非常感谢! - U_jex

2

PKPDmisc 包提供了一种与 dplyr 兼容的方式来完成此操作:

library(PKPDmisc)
df %>% strip_attributes(c("label", "labels"))

1
在某些情况下,修改@maurits-evers的答案可能会很有用。
创建一个函数来删除属性。
remove_attributes <- function(x) {attributes(x) <- NULL; return(x)}

从列表中删除一个元素的属性。
df1$V1 <- remove_attributes(df1$V1)

从列表中删除所有元素的属性。
df1 <- lapply(df1, remove_attributes)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接