【问题标题】:Create nested attribute for a new column in a data frame为数据框中的新列创建嵌套属性
【发布时间】:2021-05-15 23:14:54
【问题描述】:

我正在处理具有特定标签的数据(例如在社会科学研究中很常见)。特别是,这里列中的值不是作为因子存储的,而是作为包含标签(作为属性)的数字列存储的。而这些标签又具有属性(标签的名称)。

现在,我知道如何更改现有列的标签名称了。但是对于新列或更准确地说,我没有这样做:我知道如何使用专用包创建它们,但我想知道是否有原生/基础 R 选项,例如attrattributesstructure

示例数据:

df <- structure(list(Q16_3 = structure(c(NA, NA, 1, 1, 1, NA, NA, 1, 0, 1),
                                       label = "Q16_3 question label",
                                       format.spss = "F8.2",
                                       labels = c(`Not Selected` = 0, Selected = 1),
                                       class = c("haven_labelled", "vctrs_vctr", "double")),
                     Q16_4 = structure(c(NA, NA, 1, 1, 1, NA, NA, 0, 0, 1),
                                       label = "Q16_4 question label",
                                       format.spss = "F8.2",
                                       labels = c(`Not Selected` = 0, Selected = 1),
                                       class = c("haven_labelled", "vctrs_vctr", "double"))),
                row.names = c(NA, -10L),
                class = c("tbl_df", "tbl", "data.frame"))

例如df %&gt;% count(Q16_4) 给:

# A tibble: 3 x 2
              Q16_4     n
*         <dbl+lbl> <int>
1  0 [Not Selected]     2
2  1 [Selected]         4
3 NA                    4

现在我正在创建一个列并尝试创建一个“标签”属性,但它无法显示:

df <- df %>%
  mutate(test = rep(1:2, 5))

df$test <- structure(df$test, labels = c("NO" = 1, "YES" = 2))

df %>%
  count(test)

只给:

# A tibble: 2 x 2
   test     n
* <int> <int>
1     1     5
2     2     5

我猜它有什么。与属性本身的结构有关,因为它们看起来不同:

str(df)

tibble [10 x 3] (S3: tbl_df/tbl/data.frame)
 $ Q16_3: dbl+lbl [1:10] NA, NA,  1,  1,  1, NA, NA,  1,  0,  1
   ..@ label      : chr "Q16_3 question label"
   ..@ format.spss: chr "F8.2"
   ..@ labels     : Named num [1:2] 0 1
   .. ..- attr(*, "names")= chr [1:2] "1 Selected" "2 Selected"
 $ Q16_4: dbl+lbl [1:10] NA, NA,  1,  1,  1, NA, NA,  0,  0,  1
   ..@ label      : chr "Q16_4 question label"
   ..@ format.spss: chr "F8.2"
   ..@ labels     : Named num [1:2] 0 1
   .. ..- attr(*, "names")= chr [1:2] "NO NO" "YES YES"
 $ test : int [1:10] 1 2 1 2 1 2 1 2 1 2
  ..- attr(*, "labels")= Named num [1:2] 1 2
  .. ..- attr(*, "names")= chr [1:2] "NO" "YES"

长话短说:我需要如何更改我的代码以允许创建此类“嵌套”属性?

【问题讨论】:

  • 你期待什么输出?我不确定我是否理解正确。
  • 不是汇总输出。我想在数据中更改它(以便它正确显示在输出中)。所以在第一个例子中,它是数据中的“正确”标签,也显示在计数表中。在我的第二个示例中,数据似乎没问题(但我猜不是),因为它没有出现在输出中。所以想法是将标签添加到数据中,使其呈现与我的第一个示例相同的输出。

标签: r attributes label structure attr


【解决方案1】:

您可以使用attr 提取标签并使用match 替换它们。

var <- attr(df$test, 'labels')
df$test_label <- names(var)[match(df$test, var)]
df

#               Q16_3             Q16_4  test test_label
#           <dbl+lbl>         <dbl+lbl> <int> <chr>     
# 1 NA                NA                    1 NO        
# 2 NA                NA                    2 YES       
# 3  1 [Selected]      1 [Selected]         1 NO        
# 4  1 [Selected]      1 [Selected]         2 YES       
# 5  1 [Selected]      1 [Selected]         1 NO        
# 6 NA                NA                    2 YES       
# 7 NA                NA                    1 NO        
# 8  1 [Selected]      0 [Not Selected]     2 YES       
# 9  0 [Not Selected]  0 [Not Selected]     1 NO        
#10  1 [Selected]      1 [Selected]         2 YES       

如果您想替换原来的test 列,请将其分配给上面的df$test &lt;-


在您的原始数据框中,您拥有的已标记数据可以通过这种方式构建:

library(dplyr)

df %>%
  mutate(test = haven::labelled(rep(1:2, 5), labels = c("NO" = 1, "YES" = 2)))

#          Q16_3             Q16_4      test
#           <dbl+lbl>         <dbl+lbl> <int+lbl>
# 1 NA                NA                  1 [NO] 
# 2 NA                NA                  2 [YES]
# 3  1 [Selected]      1 [Selected]       1 [NO] 
# 4  1 [Selected]      1 [Selected]       2 [YES]
# 5  1 [Selected]      1 [Selected]       1 [NO] 
# 6 NA                NA                  2 [YES]
# 7 NA                NA                  1 [NO] 
# 8  1 [Selected]      0 [Not Selected]   2 [YES]
# 9  0 [Not Selected]  0 [Not Selected]   1 [NO] 
#10  1 [Selected]      1 [Selected]       2 [YES]

它的标签也会显示在count 中:

df %>%
  mutate(test = haven::labelled(rep(1:2, 5),labels = c("NO" = 1, "YES" = 2))) %>%
  count(test)

#      test     n
#* <int+lbl> <int>
#1   1 [NO]      5
#2   2 [YES]     5

【讨论】:

  • 谢谢,但这只会更改聚合输出表。我需要它在数据中。
  • 只是为了理解它:这段代码将是我上面标签设置的补充,它会将变量更改为一个字符,对吗?它不会保留数据的数字结构并添加标签作为属性?
  • 原始数据中的数据是有标签的数据,新数据中也可以有类似的格式(检查更新的答案),但它不是基础 R。
  • 是的,想知道是否有一个简单的基本 R 方法来“复制”have::labelled 行为,即创建一个具有良好标签的数字变量。但是我可以通过专用包来解决。
猜你喜欢
  • 2018-05-08
  • 2022-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-18
  • 1970-01-01
  • 1970-01-01
  • 2014-08-06
相关资源
最近更新 更多