简体   繁体   English

通过字符串匹配出现递归地添加列 R gsub regex

[英]Add columns recursively by string match occurrence R gsub regex

I have an R df where one column, Author, looks like this (the names themselves are replaced by 'Last' and 'First' in this post for anonymity):我有一个 R df,其中一列 Author 看起来像这样(为了匿名,在这篇文章中,名称本身被替换为“Last”和“First”):

id ID Author作者
1 1 Last, First & Last, First最后,第一和最后,第一
2 2 Last, First & Last, First & Last, First & Last, First最后,第一个和最后一个,第一个和最后一个,第一个和最后一个,第一个
3 3 Last, First & Last, First & Last, First最后,第一个和最后一个,第一个和最后一个,第一个

I need to add a new column for the first and last name of every author.我需要为每个作者的名字和姓氏添加一个新列。 It should look like this:它应该如下所示:

id ID First1第一1 Last1最后1 First2第一2 Last2最后2 First3第一3 Last3最后3 First4第一4 Last4最后4
1 1 First第一的 Last最后的 First第一的 Last最后的
2 2 First第一的 Last最后的 First第一的 Last最后的 First第一的 Last最后的 First第一的 Last最后的
3 3 First第一的 Last最后的 First第一的 Last最后的 First第一的 Last最后的

Of course, not all readings have the same number of authors, so I'm unable to append a specific number of columns for all rows.当然,并非所有读数都具有相同数量的作者,因此我无法为所有行 append 指定特定数量的列。

** NOTE: I've done this for columns that only have one author using ** 注意:我已经为只有一位作者使用的列完成了此操作

data <- data %>% 
  mutate(FirstName=unlist(lapply(strsplit(Author,", "),function(x) x[2])),
         LastName=gsub(",.*","",Author))

How can I do this?我怎样才能做到这一点?

One option can be:一种选择可以是:

df %>%
 mutate(map_dfr(.x = str_split(Author, ", | & "),
                ~ set_names(.x, ave(.x, .x, FUN = function(y) paste0(y, cumsum(duplicated(y)) + 1)))))

  id                                                Author Last1 First1 Last2 First2 Last3 First3 Last4 First4
1  1                             Last, First & Last, First  Last  First  Last  First  <NA>   <NA>  <NA>   <NA>
2  2 Last, First & Last, First & Last, First & Last, First  Last  First  Last  First  Last  First  Last  First
3  3               Last, First & Last, First & Last, First  Last  First  Last  First  Last  First  <NA>   <NA>

Here I use a small helper function to return a list of last and first names这里我使用了一个小助手 function 来返回姓氏和名字的列表

get_names <- function(x) {
  authors = strsplit(x, " & ")[[1]]
  lapply(authors, \(a) setNames(strsplit(a, ", ")[[1]], c("Last", "First")))
}

Then I apply it to each id , unnest, and pivot wide然后我将它应用于每个id 、 unnest 和 pivot 宽

df %>% 
  group_by(id) %>% 
  summarize(names=list(get_names(Author))) %>% 
  unnest(names) %>% 
  unnest_wider(names) %>% 
  group_by(id) %>% 
  mutate(rn=row_number()) %>% 
  pivot_wider(id, names_from =rn, names_sep="",values_from = c(First,Last),names_vary="slowest")

Here's a version using tidyr::separate :这是使用tidyr::separate的版本:

library(tidyr)
library(stringr)
n_auth = max(str_count(df$Author, pattern = "&")) + 1
df %>%
  separate(
    Author,
    sep = " *[,&] ",
    into = c(outer(c("First", "Last"), 1:n_auth, FUN = paste0)),
    fill = "right"
)
#   id First1 Last1 First2 Last2 First3 Last3 First4 Last4
# 1  1   Last First   Last First   <NA>  <NA>   <NA>  <NA>
# 2  2   Last First   Last First   Last First   Last First
# 3  3   Last First   Last First   Last First   <NA>  <NA>

In base R you will do:在基础 R 中,您将执行以下操作:

(df1 <- read.table(text=gsub('[,&]', '', df$Author), fill=TRUE))

   V1    V2   V3    V4   V5    V6   V7    V8
1 Last First Last First                      
2 Last First Last First Last First Last First
3 Last First Last First Last First         

You can then add names:然后,您可以添加名称:

names(df1)<-paste0(c("Last", "First"), gl(ncol(df1), 2,ncol(df1)))
df1

  Last1 First1 Last2 First2 Last3 First3 Last4 First4
1  Last  First  Last  First                          
2  Last  First  Last  First  Last  First  Last  First
3  Last  First  Last  First  Last  First         

of course you can rearrange the table to have first before last :当然,您可以将表格重新排列为firstlast

df1[order(sub("\\D+", '',names(df1)), sub("\\d+", '', names(df1)))]

  First1 Last1 First2 Last2 First3 Last3 First4 Last4
1  First  Last  First  Last                          
2  First  Last  First  Last  First  Last  First  Last
3  First  Last  First  Last  First  Last    

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM