【问题标题】:Merge data.frame columns by label attribute?按标签属性合并data.frame列?
【发布时间】:2021-08-06 11:51:49
【问题描述】:

假设您有一个 data.frame,其中某些列具有“标签”属性。

df1 <- data.frame(ID = letters[1:3], Qr1 = 1:3, Qr2 = 4:6, Qr3 = 7:9)
attr(df1$Qr1, 'label') <- 'dog'
attr(df1$Qr2, 'label') <- 'cat'
attr(df1$Qr3, 'label') <- 'bird'

您还有第二个类似的 data.frame,但变量不同 词干(“问题”而不是“Q”)。还有一个带有“标签”的新变量 'fish' 的属性,并且变量被重新排序('cat' 现在是第三个,'bird' 现在是序列中的第四个。)

df2 <- data.frame(ID = letters[4:6], Questionr1 = 10:12, Questionr2 = 13:15, 
                  Questionr3 = 16:18, Questionr4 = 19:21)
attr(df2$Questionr1, 'label') <- 'dog'
attr(df2$Questionr2, 'label') <- 'fish'
attr(df2$Questionr3, 'label') <- 'cat'
attr(df2$Questionr4, 'label') <- 'bird'

您的目标是将“df1”与“df2”对齐,以便“df3”将它们的数据与 关于“标签”属性,它遵循“df2”的变量命名(有更多变量的变量):

> goal
  ID Questionr1 Questionr2 Questionr3 Questionr4
1  a          1         NA          4          7
2  b          2         NA          5          8
3  c          3         NA          6          9
4  d         10         13         16         19
5  e         11         14         17         20
6  f         12         15         18         21

在使用dplyr::bind_rows() 绑定行之前,我尝试使用'label' 属性中保存的字符串重命名列。这适用于我的示例数据,有点,但不适用于我的实际数据(我认为是因为我的标签值很长)。

# rename columns by label for df1
temp1 <- df1
stem1 <- '^Qr'
idx1 <- grep(stem1, colnames(temp1))
nams1 <- colnames(temp1)[idx1]

for(i in seq_along(nams1)){
  
  lab1 <- attr(temp1[[nams1[i]]], "label")
  names(temp1) <- gsub(nams1[i], lab1, names(temp1))
  
}

# renames columns by label for df2
temp2 <- df2
stem2 <- "^Questionr"
idx2 <- grep(stem2, colnames(temp2))
nams2 <- colnames(temp2)[idx2]

for(i in seq_along(nams2)){
  
  lab2 <- attr(temp2[[nams2[i]]], "label")
  names(temp2) <- gsub(nams2[i], lab2, names(temp2))
  
}            

# bind the temp dfs
temp21 <- dplyr::bind_rows(temp2, temp1)
names(temp21) <- colnames(df2)

> temp21
ID Questionr1 Questionr2 Questionr3 Questionr4
1  d         10         13         16         19
2  e         11         14         17         20
3  f         12         15         18         21
4  a          1         NA          4          7
5  b          2         NA          5          8
6  c          3         NA          6          9

是否有一个函数或更直接的方法,我可以使用它们的属性标签来合并这些 data.frame 列?理想情况下,我希望得到具有更多主干变量的 data.frame 的原始变量名称。

【问题讨论】:

    标签: r


    【解决方案1】:

    这是使用tidyverse 的(稍微不那么乏味的)方法:

    为“较大”数据帧 (df2) 中的属性 (label) 和问题 (QR) 定义一个查找表,并为查找和读取属性定义两个辅助函数。

    library(tidyverse)
    
    get_label <- attr_getter("label")
    
    lut <- tibble(Qr = df2 %>% select(-ID) %>% names) %>% 
      mutate(label = map_chr(Qr, ~ get_label(df2[[.]])))
    
    lookup <- function(x) lut %>% filter(label == x) %>% pull(Qr)
    

    用相应的标签重命名df1df2 中的列,连接并重命名结果的列。

    goal <- full_join(
      df1 %>% rename_with(~ map_chr(.x, ~ get_label(df1[[.]])), .cols = -ID),
      df2 %>% rename_with(~ map_chr(.x, ~ get_label(df2[[.]])), .cols = -ID)
    ) %>% rename_with(~ map_chr(.x, ~lookup(.)), .cols = -ID) 
    
    goal %>% select(sort(names(goal))) # optional reordering of columns
    
      ID Questionr1 Questionr2 Questionr3 Questionr4
    1  a          1         NA          4          7
    2  b          2         NA          5          8
    3  c          3         NA          6          9
    4  d         10         13         16         19
    5  e         11         14         17         20
    6  f         12         15         18         21
    

    【讨论】:

      猜你喜欢
      • 2021-08-13
      • 2018-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多