通过考虑r(2)中的分组Q矩阵来操纵字符向量 [英] Manipulating a character vector by considering a grouping Q-matrix in r (2)

查看:57
本文介绍了通过考虑r(2)中的分组Q矩阵来操纵字符向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试基于 Group 变量 item.map 编写代码,其中包含以下项信息:

I am trying to write code based on a Group variable, item.map that has item information that includes an q-matrix showing which item is associated with which group.

    Group <- c(1,2,3,4)
item.map <- data.frame(
  item.id = c(21,41,61,72),
  group.1 = c(1,1,1,0),
  group.2 = c(0,1,0,1),
  group.3 = c(1,1,1,0),
  group.4 = c(0,0,0,1))

> item.map
  item.id group.1 group.2 group.3 group.4
1      21       1       0       1       0
2      41       1       1       1       0
3      61       1       0       1       0
4      72       0       1       0       1

在此 item.map中 group.1有3个项目,而group.2有2个项目, group.3 有3个项目,而 group.4 有1个项目。使用此item.map,我想在下面的代码块中分配这些项目,但无法插入 item.map

In this item.map group.1 had 3 items while group.2 has two items, group.3 has three and group.4 has 1 item.. Using this item.map I wanted to assign those items within the chunk of code below but I was not able to plug the item.map information.

   OUTPUT <- as.data.frame(c())
for(i in 1:length(item.map$item.id)) {
 
  for(k in 0:(length(Group))) { # here with the length(State) I gained the sequqnece of 0,1,2,3
    output <- paste0("Equal = ",paste0(paste("(", "G1, ",item.map$item.id[i], ","," Slope[",k,"])",collapse=", ", sep=""),", ",
                                        paste( "(", "G2, ",item.map$item.id[i], ","," Slope[",k,"])",collapse=", ", sep=""),
                                        ";"))
    OUTPUT <- c(OUTPUT, output)
    
  }
}


[1] "Equal = (G1, 21, Slope[0]), (G2, 21, Slope[0]), (G3, 21, Slope[0]), (G4, 21, Slope[0]);"
[1] "Equal = (G1, 21, Slope[1]), (G2, 21, Slope[1]), (G3, 21, Slope[1]), (G4, 21, Slope[1]);"
[1] "Equal = (G1, 21, Slope[2]), (G2, 21, Slope[2]), (G3, 21, Slope[2]), (G4, 21, Slope[2]);"
[1] "Equal = (G1, 21, Slope[3]), (G2, 21, Slope[3]), (G3, 21, Slope[3]), (G4, 21, Slope[3]);"
[1] "Equal = (G1, 21, Slope[4]), (G2, 21, Slope[4]), (G3, 21, Slope[4]), (G4, 21, Slope[4]);"
[1] "Equal = (G1, 41, Slope[0]), (G2, 41, Slope[0]), (G3, 41, Slope[0]), (G4, 41, Slope[0]);"
[1] "Equal = (G1, 41, Slope[1]), (G2, 41, Slope[1]), (G3, 41, Slope[1]), (G4, 41, Slope[1]);"
[1] "Equal = (G1, 41, Slope[2]), (G2, 41, Slope[2]), (G3, 41, Slope[2]), (G4, 41, Slope[2]);"
[1] "Equal = (G1, 41, Slope[3]), (G2, 41, Slope[3]), (G3, 41, Slope[3]), (G4, 41, Slope[3]);"
[1] "Equal = (G1, 41, Slope[4]), (G2, 41, Slope[4]), (G3, 41, Slope[4]), (G4, 41, Slope[4]);"
[1] "Equal = (G1, 61, Slope[0]), (G2, 61, Slope[0]), (G3, 61, Slope[0]), (G4, 61, Slope[0]);"
[1] "Equal = (G1, 61, Slope[1]), (G2, 61, Slope[1]), (G3, 61, Slope[1]), (G4, 61, Slope[1]);"
[1] "Equal = (G1, 61, Slope[2]), (G2, 61, Slope[2]), (G3, 61, Slope[2]), (G4, 61, Slope[2]);"
[1] "Equal = (G1, 61, Slope[3]), (G2, 61, Slope[3]), (G3, 61, Slope[3]), (G4, 61, Slope[3]);"
[1] "Equal = (G1, 61, Slope[4]), (G2, 61, Slope[4]), (G3, 61, Slope[4]), (G4, 61, Slope[4]);"
[1] "Equal = (G1, 72, Slope[0]), (G2, 72, Slope[0]), (G3, 72, Slope[0]), (G4, 72, Slope[0]);"
[1] "Equal = (G1, 72, Slope[1]), (G2, 72, Slope[1]), (G3, 72, Slope[1]), (G4, 72, Slope[1]);"
[1] "Equal = (G1, 72, Slope[2]), (G2, 72, Slope[2]), (G3, 72, Slope[2]), (G4, 72, Slope[2]);"
[1] "Equal = (G1, 72, Slope[3]), (G2, 72, Slope[3]), (G3, 72, Slope[3]), (G4, 72, Slope[3]);"
[1] "Equal = (G1, 72, Slope[4]), (G2, 72, Slope[4]), (G3, 72, Slope[4]), (G4, 72, Slope[4]);"

因此,在所需的输出中, G1 不应该包含项目 72 和G2不应包含项目 21 61 的信息在分组块中。
另外,我无法对 G1进行排序。和 G2;在我的代码中。考虑到 G1 G2 G3 G4

So, in the desired output, G1 should not have item 72 and G2 should not have items 21 and 61 information in the grouping chunk. Also, I was not able to sequence "G1" and "G2" in my code. Is there a way to combine these two lines into one considering G1, G2, G3 and G4?

output <- paste0("Equal = ",paste0(paste("(", "G1, ",item.map$item.id[i], ","," Slope[",k,"])",collapse=", ", sep=""),", ",
                                       paste("(", "G2, ",item.map$item.id[i], ","," Slope[",k,"])",collapse=", ", sep=""),", ",
                                       paste("(", "G3, ",item.map$item.id[i], ","," Slope[",k,"])",collapse=", ", sep=""),", ",
                                       paste( "(", "G4, ",item.map$item.id[i], ","," Slope[",k,"])",collapse=", ", sep=""),
                                       
                                       ";"))

所需的输出为:

[1] "Equal = (G1, 21, Slope[0]), (G3, 21, Slope[0]);"
[1] "Equal = (G1, 21, Slope[1]), (G3, 21, Slope[1]);"
[1] "Equal = (G1, 21, Slope[2]), (G3, 21, Slope[2]);"
[1] "Equal = (G1, 21, Slope[3]), (G3, 21, Slope[3]);"
[1] "Equal = (G1, 21, Slope[4]), (G3, 21, Slope[4]);"
[1] "Equal = (G1, 41, Slope[0]), (G2, 41, Slope[0]), (G3, 41, Slope[0]);"
[1] "Equal = (G1, 41, Slope[1]), (G2, 41, Slope[1]), (G3, 41, Slope[1]);"
[1] "Equal = (G1, 41, Slope[2]), (G2, 41, Slope[2]), (G3, 41, Slope[2]);"
[1] "Equal = (G1, 41, Slope[3]), (G2, 41, Slope[3]), (G3, 41, Slope[3]);"
[1] "Equal = (G1, 41, Slope[4]), (G2, 41, Slope[4]), (G3, 41, Slope[4]);"
[1] "Equal = (G1, 61, Slope[0]), (G3, 61, Slope[0]);"
[1] "Equal = (G1, 61, Slope[1]), (G3, 61, Slope[1]);"
[1] "Equal = (G1, 61, Slope[2]), (G3, 61, Slope[2]);"
[1] "Equal = (G1, 61, Slope[3]), (G3, 61, Slope[3]);"
[1] "Equal = (G1, 61, Slope[4]), (G3, 61, Slope[4]);"
[1] "Equal = (G2, 72, Slope[0]), (G4, 72, Slope[0]);"
[1] "Equal = (G2, 72, Slope[1]), (G4, 72, Slope[1]);"
[1] "Equal = (G2, 72, Slope[2]), (G4, 72, Slope[2]);"
[1] "Equal = (G2, 72, Slope[3]), (G4, 72, Slope[3]);"
[1] "Equal = (G2, 72, Slope[4]), (G4, 72, Slope[4]);"

有人有什么想法吗?
谢谢

Does anyone have any ideas? Thanks

推荐答案

这里是 tidyverse 的一种选择我们遍历组列名称,选择来自列表,重命名到'G1','G2',然后执行交叉扩展数据集, filter 基于逻辑组列,使用 glue_data (来自 grlue )和展平 列表向量

Here is one option with tidyverse where we loop over the 'group' column names, select those from 'item.map in a list, rename it to 'G1', 'G2', then do crossing to expand the dataset, filter based on the logical group column, create the expression with glue_data (from grlue) and flatten the list to a vector

library(dplyr)
library(purrr)
library(stringr)
out <- map(c('group.1', 'group.2'), 
      ~ item.map %>% 
          select(item.id, .x) %>% 
          rename_at(.x, ~ str_c('G', str_remove(., "\\D+"))) %>% 
          crossing(k = 0:2) %>%
          filter(across(starts_with('G'), as.logical)) %>% 
          glue::glue_data("Equal = ({names(.)[2]}, {item.id}, Slope[{k}]);")%>%
          as.character) %>%
    flatten_chr

-输出

out
#[1] "Equal = (G1, 21, Slope[0]);" "Equal = (G1, 21, Slope[1]);" "Equal = (G1, 21, Slope[2]);" "Equal = (G1, 41, Slope[0]);"
#[5] "Equal = (G1, 41, Slope[1]);" "Equal = (G1, 41, Slope[2]);" "Equal = (G1, 61, Slope[0]);" "Equal = (G1, 61, Slope[1]);"
#[9] "Equal = (G1, 61, Slope[2]);" "Equal = (G2, 41, Slope[0]);" "Equal = (G2, 41, Slope[1]);" "Equal = (G2, 41, Slope[2]);"
#[13] "Equal = (G2, 72, Slope[0]);" "Equal = (G2, 72, Slope[1]);" "Equal = (G2, 72, Slope[2]);"

如果我们希望将两个都为1的分组,

If we want to group those that are 1 in both groups,

i1 <- ave(seq_along(out), sub("G\\d+", "", out), FUN = length)

 out[i1 > 1] <- ave(out[i1 > 1], sub("Equal = \\(G\\d+", "", out[i1 > 1]), 
      FUN = function(x) {
          x[1] <- sub(";", "", x[1])
          paste(x[1], sub("Equal = ", "", x[2]), sep =", ")
  })
out1 <- unique(out)
out1

#[1] "Equal = (G1, 21, Slope[0]);"                     "Equal = (G1, 21, Slope[1]);"                    
#[3] "Equal = (G1, 21, Slope[2]);"                     "Equal = (G1, 41, Slope[0]), (G2, 41, Slope[0]);"
#[5] "Equal = (G1, 41, Slope[1]), (G2, 41, Slope[1]);" "Equal = (G1, 41, Slope[2]), (G2, 41, Slope[2]);"
#[7] "Equal = (G1, 61, Slope[0]);"                     "Equal = (G1, 61, Slope[1]);"                    
#[9] "Equal = (G1, 61, Slope[2]);"                     "Equal = (G2, 72, Slope[0]);"                    
#[11] "Equal = (G2, 72, Slope[1]);"                     "Equal = (G2, 72, Slope[2]);"  


更新


使用已更新的数据集

Update

With the updated dataset

out <- map(c('group.1', 'group.2', 'group.3', 'group.4'), 
       ~ item.map %>% 
            select(item.id, .x) %>% 
            rename_at(.x, ~ str_c('G', str_remove(., "\\D+"))) %>% 
            crossing(k = 0:4) %>%
            filter(across(starts_with('G'), as.logical)) %>% 
            glue::glue_data("Equal = ({names(.)[2]}, {item.id}, Slope[{k}]);")%>%
            as.character) %>%
      flatten_chr
 
out[i1 > 1] <- ave(out[i1 > 1], sub("Equal = \\(G\\d+", "", out[i1 > 1]),
     FUN = function(x) {
      x[-length(x)] <- sub(";", "", x[-length(x)])
      paste(x[1], paste(sub("Equal = ", "", x[-1]), collapse = ", "), sep=", ") 
   })
   
unique(out)
 [1] "Equal = (G1, 21, Slope[0]), (G3, 21, Slope[0]);"                    
 [2] "Equal = (G1, 21, Slope[1]), (G3, 21, Slope[1]);"                    
 [3] "Equal = (G1, 21, Slope[2]), (G3, 21, Slope[2]);"                    
 [4] "Equal = (G1, 21, Slope[3]), (G3, 21, Slope[3]);"                    
 [5] "Equal = (G1, 21, Slope[4]), (G3, 21, Slope[4]);"                    
 [6] "Equal = (G1, 41, Slope[0]), (G2, 41, Slope[0]), (G3, 41, Slope[0]);"
 [7] "Equal = (G1, 41, Slope[1]), (G2, 41, Slope[1]), (G3, 41, Slope[1]);"
 [8] "Equal = (G1, 41, Slope[2]), (G2, 41, Slope[2]), (G3, 41, Slope[2]);"
 [9] "Equal = (G1, 41, Slope[3]), (G2, 41, Slope[3]), (G3, 41, Slope[3]);"
[10] "Equal = (G1, 41, Slope[4]), (G2, 41, Slope[4]), (G3, 41, Slope[4]);"
[11] "Equal = (G1, 61, Slope[0]), (G3, 61, Slope[0]);"                    
[12] "Equal = (G1, 61, Slope[1]), (G3, 61, Slope[1]);"                    
[13] "Equal = (G1, 61, Slope[2]), (G3, 61, Slope[2]);"                    
[14] "Equal = (G1, 61, Slope[3]), (G3, 61, Slope[3]);"                    
[15] "Equal = (G1, 61, Slope[4]), (G3, 61, Slope[4]);"                    
[16] "Equal = (G2, 72, Slope[0]), (G4, 72, Slope[0]);"                    
[17] "Equal = (G2, 72, Slope[1]), (G4, 72, Slope[1]);"                    
[18] "Equal = (G2, 72, Slope[2]), (G4, 72, Slope[2]);"                    
[19] "Equal = (G2, 72, Slope[3]), (G4, 72, Slope[3]);"                    
[20] "Equal = (G2, 72, Slope[4]), (G4, 72, Slope[4]);"       




或嵌套循环

OUTPUT <- c()
# // loop over the sequence of rows
for(i in seq_len(nrow(item.map))) {
    # // nested loop to expand on a sequence
    for(k in  0:2) {  
        # // do a second nest based on the 'Group'  
         for(j in seq_along(Group)) {
              # // create a logical expression based on the 'group' column
              i1 <- as.logical(item.map[[paste0("group.", j)]][i])
              # // if it is TRUE, then only do the below
              if(i1) {
                  # // create the expression with paste
                  output <- paste0("Equal = ", paste("(", "G", j, 
                     ", ", item.map$item.id[i], ", Slope[", k, "])", 
                         collapse=", ", sep=""))
                 
              # // concatenate the NULL vector with the temporary output
              OUTPUT <- c(OUTPUT, output)
              }
         
         }
    
    }

}

这篇关于通过考虑r(2)中的分组Q矩阵来操纵字符向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆