当前位置: 首页 > 知识库问答 >
问题:

基于列组合行的R数据frame

单展
2023-03-14
+---------+-----------+------------+---------------+
| Varname | Component |   names    |    cities     |
+---------+-----------+------------+---------------+
| A       | B         | Jack,Bruce | New york      |
| B       |           | Cathy      | Boston,Miami  |
| C       |           | Bob        | New york      |
| D       | C         | Dick,Nancy | Austin,Dallas |
| E       | A,C       |            |               |
| F       |           | Mandy      | Manchester    |
+---------+-----------+------------+---------------+
+---------+-----------+----------------------+------------------------+
| Varname | Component |        names         |         cities         |
+---------+-----------+----------------------+------------------------+
| A       |           | Jack,Bruce,Cathy     | New york,Boston,Miami  |
| B       |           | Cathy                | Boston,Miami           |
| C       |           | Bob                  | New york               |
| D       |           | Dick,Nancy,Bob       | Austin,Dallas,New york |
| E       |           | Jack,Bruce,Cathy,Bob | New york,Boston,Miami  |
| F       |           | Mandy                | Manchester             |
+---------+-----------+----------------------+------------------------+

输入的dput()

结构(列表(Varname=structure(1:6,.标签=c(“A”,“B”,“c”,“D”,“E”,“F”),类=“因子”),成分=结构(c(3L,1L,1L,4L,2L,1L),标签=c(“”,“A,c”,“B”,“c”),类=“因子”),名字=结构(c(5L,3L,2L,4L,6L),标签=c(“”,“鲍勃”,“凯茜”,“迪克,南希”,“杰克,布鲁斯”,“曼迪”),类=“因子”),城市=结构(c(5L,3L,5L,2L,2L,4L,4L),标签=c(“奥斯汀”,达拉斯“,”波士顿,迈阿密“,”曼彻斯特“,”纽约“),class=”因子“),.names=c(”varname“,”Component“,”names“,”cithtml" target="_blank">ions“),class=”data.frame“,row.names=c(NA,-6L))

共有1个答案

满子实
2023-03-14

不是最吸引人的R代码(也肯定不是最有效的),但它完成了工作。希望其他人能改进它。

starting_df <- read.table(text="Varname|Component|names|cities     
A||Jack,Bruce|New york
B||Cathy|Boston,Miami
C|A|Bob|New york
D|C|Dick,Nancy|Austin,Dallas",header=T, sep="|", stringsAsFactors=F)

##Grab all the rows whose Component values are in the Varname column and vice-versa
intermediate_df <- starting_df[(starting_df$Varname %in% starting_df$Component | starting_df$Component %in% starting_df$Varname ),]

##Change the rows in the names and cities columns to match your desired output (sorry about the for loop)
for (x in 1:nrow(intermediate_df)) {
  if (x == 1) {
    intermediate_df[x,'names'] <- intermediate_df$names[x]
    intermediate_df[x,'cities'] <- intermediate_df$cities[x]
  } else {
    intermediate_df[x,'names'] <- paste0(unique(unlist(strsplit(paste(intermediate_df$names[x-1],intermediate_df$names[x],sep = ","),split=","))),collapse=",")
    intermediate_df[x,'cities'] <- paste0(unique(unlist(strsplit(paste(intermediate_df$cities[x-1],intermediate_df$cities[x],sep = ","),split=","))),collapse=",")
  }
}

##Binding the new dataset with the starting dataset (but only Varnames that are in the new dataset)
final_df <- rbind(intermediate_df,starting_df[!(starting_df$Varname %in% intermediate_df$Varname),])

##Order by the Varname column to get the desired output
final_df <- final_df[order(final_df$Varname),]

您想要的输出:

 Varname Component names                     cities                
 A                 Jack,Bruce                New york              
 B                 Cathy                     Boston,Miami          
 C       A         Jack,Bruce,Bob            New york              
 D       C         Jack,Bruce,Bob,Dick,Nancy New york,Austin,Dallas

这个函数使用了for循环的循环(我在R中根本不喜欢这样做),但它似乎产生了一些东西:

##Setting up the new dataset
starting_df1 <- structure(list(Varname = structure(1:6, .Label = c("A", "B", "C", "D", "E", "F"), class = "factor"), 
                              Component = structure(c(3L, 1L, 1L, 4L, 2L, 1L), .Label = c("", "A,C", "B", "C"), class = "factor"), 
                              names = structure(c(5L, 3L, 2L, 4L, 1L, 6L), .Label = c("", "Bob", "Cathy", "Dick,Nancy", "Jack,Bruce", "Mandy"), class = "factor"), 
                              cities = structure(c(5L, 3L, 5L, 2L, 1L, 4L), .Label = c("", "Austin,Dallas", "Boston,Miami", "Manchester", "New york" ), class = "factor")), 
                         .Names = c("Varname", "Component", "names", "cities"), class = "data.frame", row.names = c(NA, -6L ))

##Change the fields from factor variables to characters (so that you can use them for concatenating)
starting_df1 <- data.frame(apply(starting_df1, 2, FUN = function(x) {
  as.character(x)
}), stringsAsFactors = F)

##Nested for loops: For every row that has a value for the Component column, find its matches (and their indices) in the Varname column
##Then for the combination of indices to change the values you wish to change through concatenation operations for both the names and cities columns
for (i in which(!nchar(starting_df1$Component)==0)) {
  holder <- which(grepl(paste0(unlist(strsplit(starting_df1$Component[i],split=",")),collapse="|"),starting_df1$Varname))
  for (j in holder) {
    if (nchar(starting_df1$names[i])!=0) {
      starting_df1[i, "names"] <- paste0(unique(unlist(strsplit(paste(starting_df1$names[i],starting_df1$names[j],sep = ","),split=","))),collapse=",")
      starting_df1[i, "cities"] <- paste0(unique(unlist(strsplit(paste(starting_df1$cities[i],starting_df1$cities[j],sep = ","),split=","))),collapse=",")
    } else {
      starting_df1[i, "names"] <- starting_df1$names[j]
      starting_df1[i, "cities"] <- starting_df1$cities[j]
    }
  }
}

print(starting_df1, row.names = F, right = F)
 Varname Component names                cities                
 A       B         Jack,Bruce,Cathy     New york,Boston,Miami 
 B                 Cathy                Boston,Miami          
 C                 Bob                  New york              
 D       C         Dick,Nancy,Bob       Austin,Dallas,New york
 E       A,C       Jack,Bruce,Cathy,Bob New york,Boston,Miami 
 F                 Mandy                Manchester            
 类似资料:
  • 我有一些数据,其中每个id由不同的类型测量,这些类型可以有不同的值。测量值为val。一个小的虚拟数据如下所示: 那么df是: 我需要传播/投射数据,以便每个id的

  • 本文向大家介绍如何基于R数据帧列的值获取行索引?,包括了如何基于R数据帧列的值获取行索引?的使用技巧和注意事项,需要的朋友参考一下 R数据帧的一行可以在列中具有多种方式,并且这些值可以是数字,逻辑,字符串等。基于行号查找值很容易,但是基于值查找行号却很不同。如果要在特定列中查找特定值的行号,则可以提取整行,这似乎是一种更好的方法,可以使用单个方括号来获取行的子集。 示例 请看以下数据帧- 输出结果

  • data.table,我们可以根据行号或条件选择行: 但是,我不能同时选择行数和条件: 这可能是因为在这种格式下没有被解释为行号。我知道我可以链接这两个条件: 但是我想为这个子集分配新的列值 现在,它只为中间链接的 data.table 创建了列。我可以保存中间表,然后合并回原始表,但那会很麻烦。 实际上,我经常觉得 需要一个正确的行号。一个依赖于组的动态数字,但我想要一个可以识别每一行的唯一ID

  • 为此,我尝试使用lapply和一个自定义函数: 我知道我可以用一堆联合声明来做到这一点,或者也许有一种方法可以用循环和联合来做到这一点。但是考虑到需要遍历的列数,我想尝试用一种更优雅的方式来完成它。

  • 我有一个不同长度的数据帧列表(df),按年份索引,数据的代理如下所示: