【问题标题】:How to flatten dataframe variable from another dataframe in R如何从 R 中的另一个数据框中展平数据框变量
【发布时间】:2021-07-27 15:22:54
【问题描述】:

我有两个数据框。一个用作组定义(调色板)及其各自的部分(颜色)。其中一些将由组合形成。另一方面,我有一个具有不同组组合(非严格调色板)的测试数据框,例如颜色+调色板。我想要一个最终的数据框,所有非严格调色板都有各自的部分(颜色)。


# Definition dataframe ----

n = 3

Blues   = paste0('blue',  seq_len(n))
Greens  = paste0('green', seq_len(n))
Rainbow = c('red', 'Greens')

d_create = data.frame(
  group = c(
    rep(c('Blues', 'Greens'), each = n),
    rep('Rainbow', 2)
  ),
  piece = c(Blues, Greens, Rainbow)
)

d_create

#     group  piece
# 1   Blues  blue1
# 2   Blues  blue2
# 3   Blues  blue3
# 4  Greens green1
# 5  Greens green2
# 6  Greens green3
# 7 Rainbow    red
# 8 Rainbow Greens

# Test dataframe ----

Rainbow_plus = c('orange', 'Blues', 'Rainbow')

d_test = data.frame(
  group = c(
    rep('Blues',        length(Blues)),
    rep('Rainbow_plus', length(Rainbow_plus))
  ),
  piece = c(Blues, Rainbow_plus)
)

d_test

#          group   piece
# 1        Blues   blue1
# 2        Blues   blue2
# 3        Blues   blue3
# 4 Rainbow_plus  orange
# 5 Rainbow_plus   Blues
# 6 Rainbow_plus Rainbow

# Desired dataframe ----

d_desired = data.frame(
  group = c(
    rep('Blues', n),
    rep('Rainbow_plus', (2*n+2))
  ),
  piece = c(
    Blues,
    c('orange', Blues, 'red', Greens)
  )
)

d_desired

#           group  piece
# 1         Blues  blue1
# 2         Blues  blue2
# 3         Blues  blue3
# 4  Rainbow_plus orange
# 5  Rainbow_plus  blue1
# 6  Rainbow_plus  blue2
# 7  Rainbow_plus  blue3
# 8  Rainbow_plus    red
# 9  Rainbow_plus green1
# 10 Rainbow_plus green2
# 11 Rainbow_plus green3

已编辑:

我更改了数据框示例。现在,d_create 包括:

  1. “蓝调”one_depth_group
  2. “绿党”one_depth_group
  3. “彩虹”:(mix_group) simple+one_depth_group

在 d_test 上,我们有:

  1. “蓝调”:one_depth_group
  2. “Rainbow_plus”:简单+one_depth_group+mix_group

请注意,redorange 是以前未定义的新颜色,因此它们保持不变。

我想我必须遍历d_test$piece,并检查每个部分是否存在于d_create$group。如果存在,请扩展为相应的和平。如果不是,保持不变。

lapply(d_test$piece, function(x) {
    check1 = x %in% d_create$group
    if (!check1) {
      x
    } else {
      lapply(d_test[d_test$group == x,]$piece, function(z){
        check2 = z %in% d_create$group
        if (!check2) {
          z
        } else {
          lapply(d_test[d_test$group == z, ]$piece, function(m){
            check3 = m %in% d_create$group
            if (!check3) {
              m
            } else {
              'infinite_loop'
            }
          })
        }
      })
    }

  })

但我不想编写每个可能的循环,因为在现实世界中,未来的扁平化工作将是不可预测的。也许使用while。一些帮助?谢谢

【问题讨论】:

  • 抱歉,我试图了解您想要做什么,但坦率地说,我无法理解操作。我认为您想要做的是在d_test 中扩展“组”颜色(例如绿色、红色)。因此,如果存在Greens,则d_desired 将扩展为(在这种情况下)3 行,其中包含green1green2green3。如果这是正确的,那么嵌套较少的操作将是查找“组”颜色(红色、黄色、绿色等)并为“子”颜色展开(创建新行),例如在 Reds 的情况下 --> reds1, reds2, ... redsn。这是你想要达到的目标吗?
  • 我预计会有一些误解。我发现一些困难来解释这个问题。你说的情况是正确的,如果所有扩展的需要组都是相同的嵌套深度
  • 例如,d_test 上的“mix”组是由一个简单的颜色“blue1”和一个嵌套深度的“Reds”组构建的。所以最终的“mix”将是“blue1”,“ red1", "red2" 和 "red3"。当有一些简单的或单层嵌套的组和一个由两层嵌套的 "Brown/Light/(light_brown1 ,2,3...)" 和 "Brown/Dark/(dark_brown1,2,3...)"。然后 "NewGroup" 应该扩展两次,"Reds" 只扩展一次,"blue1" 保持不变
  • 我已经修改了数据框和一些解释
  • 我认为使用 while 循环是可能的,但我无法让它工作。举个例子?

标签: r loops hierarchy flatten


【解决方案1】:

你可以编写一个while循环,在这种情况下-

  • 先将df_test(事务表)后缀1的列名改为d_create(主表)对应的列名,这样就可以开始循环,也可以定义结束点。李>
  • 在 while 循环的每次迭代中,left_join 您的事务表和主表,这样您就可以在事务表中获得一个额外的列以及相应的层次结构级别(第一层次结构中的第一级)。
  • 之后coalesce 事务表的第一列(结果)与新创建的列。
  • 只有当主表中没有其他值可以匹配时,循环才会结束,即如果创建的新列将只包含相同的值而没有额外的值。

我希望我已经把逻辑说得很清楚了。

library(dplyr)

#rename one column of d_test
d_test <- d_test %>% rename(piece1 = piece)

#actual while loop
j = 1
while(any(d_test[,(paste0('piece',j))] %in% d_create$group)){
  d_test %>% left_join(d_create, by = c('piece1' = 'group')) %>%
    rename(!!paste0('piece', j +1) := piece) %>%
    mutate(piece1 = coalesce(get(paste0('piece', j+1)), piece1)) -> d_test
  j = j +1
}

#desired output
d_test %>% select(group, piece1)

          group piece1
1         Blues  blue1
2         Blues  blue2
3         Blues  blue3
4  Rainbow_plus orange
5  Rainbow_plus  blue1
6  Rainbow_plus  blue2
7  Rainbow_plus  blue3
8  Rainbow_plus    red
9  Rainbow_plus green1
10 Rainbow_plus green2
11 Rainbow_plus green3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    • 2020-07-07
    • 2018-08-18
    • 2021-11-22
    • 2019-12-31
    相关资源
    最近更新 更多