发生时复制data.frame的每一行

时间:2016-12-13 13:55:34

标签: r database code-duplication

我面临一个棘手的问题,很乐意得到一些帮助。

我有一个ID名称采用不同结构的数据框。如下所示:

ID
bbb-5p/mi-98/6134
abb-4p
bbb-5p/mi-98

每次我有这个" /"我想复制一行。每行应该重复我们找到这个" /"的时间。 然后,复制行的名称应为" /"之后的根+字符。

例如:

ID
bbb-5p/mi-98/6134

应该给:

ID
bbb-5p
bbb-5p-mi-98
bbb-5p-6134

我的初始数据框也有5个变量:

  [ID, varA, varB, varC, varD]

每次我有这个" /"我想复制整行。然后我希望有一个像

这样的新数据框
  newID         newvarA  newvarB  newvarC  newvarD   
  bbb-5p        varA(1)  varB(1)  varC(1)  varD(1)
  bbb-5p-mi-98  varA(1)  varB(1)  varC(1)  varD(1)
  bbb-5p-6134   varA(1)  varB(1)  varC(1)  varD(1)
  abb-4p        varA(2)  varB(2)  varC(2)  varD(2)
  bbb-5p        varA(3)  varB(3)  varC(3)  varD(3)
  bbb-5p-mi-98  varA(3)  varB(3)  varC(3)  varD(3)

有什么想法吗? 提前谢谢

彼得

3 个答案:

答案 0 :(得分:1)

您可以使用$(document).ready(function () { $("#btnSubscription").click(function () { SendSubscription(); }), return false; }), function SendSubscription() { $.ajax({ type: "post", url: $("#btnSubscription").data("url"), data: { fullName: $("#txtFullName").val(), emailAddress: $("#txtEmail").val() }, success: function () { alert("email sent") }, error: function () { alert("An error occurred..") } }); } 使用自定义函数在base R中完成此操作。首先,在lapply()上拆分字符列,得到一个向量列表:

"/"

然后使用l <- strsplit(df$ID,"/") 将用户定义的函数应用于l的每个元素:

lapply()

该函数首先检查向量是否具有l_stacked <- lapply(l, function(x) if(length(x) > 1) { c(x[1], paste0(x[1],"-",x[-1])) } else { x }) 。如果是这样,它将所有元素与第一个元素连接起来,用length > 1分隔。如果"-",则表示字符串不包含length <= 1,因此会按原样返回。最后,我们使用"/"展平输出,以便能够转换为unlist()

data.frame

答案 1 :(得分:0)

实现这一目标的一种方法如下:

library(dplyr)
library(tidyr)
res <- df %>% mutate(i=row_number(),
                     ID = strsplit(ID,split='/')) %>%
              unnest() %>% 
              group_by(i) %>%
              mutate(ID=ifelse(ID==first(ID),first(ID),paste(first(ID),ID,sep='-'))) %>%
              ungroup() %>% select(-i)
### A tibble: 6 x 1
##            ID
##         <chr>
##1       bbb-5p
##2 bbb-5p-mi-98
##3  bbb-5p-6134
##4       abb-4p
##5       bbb-5p
##6 bbb-5p-mi-98

注意:

  1. 首先,创建一个索引列i以便稍后分组,以便我们可以对每个&#34; root&#34;进行分组。
  2. 使用strsplit将每行拆分为"|"
  3. tidyr::unnest分隔行的结果。
  4. group_by创建的索引i然后如果该行是第一行,则返回根目录;否则,paste将根添加到具有分隔符"-"的行。
  5. 最后,ungroup并删除创建的索引列i
  6. 数据

    df <- structure(list(ID = c("bbb-5p/mi-98/6134", "abb-4p", "bbb-5p/mi-98"
    )), .Names = "ID", row.names = c(NA, -3L), class = "data.frame")
                     ID
    1 bbb-5p/mi-98/6134
    2            abb-4p
    3      bbb-5p/mi-98
    

答案 2 :(得分:0)

以下是使用data.table的一个选项。将'data.frame'转换为'data.table'(setDT(df1, ..))并创建一列rownames,按'rn'分组,将'ID'拆分为/,循环执行序列行,paste基于索引的拆分元素。

library(splitstackshape)
library(data.table)
setDT(df1, keep.rownames=TRUE)[, unlist(strsplit(ID, "/")), 
         by = rn][, .(ID=sapply(seq_len(.N), function(i) 
             paste(V1[unique(c(1,i))], collapse="-"))) , rn]

dplyr/tidyr/tibble选项。使用tibble::rownames_to_column创建rownames列,将行分为长格式separate_rows,按'rn'分组,我们mutate'ID'paste基于元素在长度的条件下,删除'rn'列。

library(dplyr)
library(tidyr)
library(tidyr)
rownames_to_column(df1, var = "rn") %>% 
         separate_rows(ID, sep="/") %>%
         group_by(rn)  %>%
         mutate(ID = if(n()>1) c(ID[1], paste(ID[1], ID[-1], sep="-")) else ID) %>%
         ungroup() %>%
         select(-rn)
 #         ID
 #        <chr>
 #1       bbb-5p
 #2 bbb-5p-mi-98
 #3  bbb-5p-6134
 #4       abb-4p
 #5       bbb-5p 
 #6 bbb-5p-mi-98