Используя R, чтобы определить положение автора в журналах? - PullRequest
0 голосов
/ 29 января 2019

Я собираюсь проанализировать порядок авторов в научных статьях и получить набор журналов, авторов, названий публикаций, дат публикации и т. Д., С которыми я работаю.Данные приводятся с каждым заголовком публикации в виде строки, а автор (ы) статьи перечисляется в списке, разделенном точкой с запятой.Например:

authors, pubtitle, title, date
Name 1; Name 2; Name 3, Journal Title, Article Title, 2018
Name 1; Name 2, Journal Title, Article Title, 2019
Name 1; Name 2; Name 3; Name 4; Name 5, Journal Title, Article Title, 2018

Я придумала довольно неэффективный способ определения порядка авторов, но меня интересуют предложения по улучшению этого.Прямо сейчас общий рабочий процесс выглядит следующим образом:

data_name_listed <- readxl::read_xlsx("data-raw/data.xlsx")
data_name_listed <- data_name_listed %>% 
  rename(author = "Author") %>% 
  rename(title = "Title") %>% 
  rename(pubtitle = "Publication Title") %>% 
  rename(publisher = "Publisher") %>% 
  rename(date = "Date") 

# Select just the author column
data_name_order <- data_name_listed %>% select(author)
data_name_order$author <- str_trim(data_name_order$author)

# Separate lists of names into columns according to the order they appear in the comma-separated list
# This is really inelegant.
data_name_order <- data_name_order %>% 
  separate(col = author, into = c("1","2","3","4","5","6","7","8","9","10","11",
                                  "12","13","14","15", "16","17","18","19","20",
                                  "21","22","23","24","25","26","27","28","29",
                                  "30","31","32","33","34","35"), sep = ";")

# Gather the data into a tidy df
data_name_order <- data_name_order %>% 
  gather(position, name)
# Clean up special characters in names
data_name_order$name <- gsub("(.*)\\s+[A-Z]\\.?$", "\\1", data_name_order$name)
# Get rid of missing data
data_name_order <- data_name_order %>% drop_na()
# Convert position number to numeric
data_name_order$position <- as.numeric(data_name_order$position)
# Ensure no whitespace
data_name_order$name <- str_trim(data_name_order$name)
# Then merge this data with tidy journal data 
# ... code ...

В частности, функция separate() особенно запутанна, хотя кажется, что она достигла того, на что я надеялась.Я хотел бы получить любой совет, чтобы сделать его немного более чистым и более воспроизводимым / применимым к другим наборам данных.Спасибо!

1 Ответ

0 голосов
/ 29 января 2019

Вот предложение без separate:

library(dplyr)
library(tidyr)

x %>%
  select(authors) %>%
  transmute(
    id = row_number(),
    author = strsplit(authors, ";")
  ) %>%
  unnest() %>%
  group_by(id) %>%
  mutate(
    position = row_number(),
    author = trimws(author)
  ) %>%
  ungroup()
# # A tibble: 10 x 3
#       id author position
#    <int> <chr>     <int>
#  1     1 Name 1        1
#  2     1 Name 2        2
#  3     1 Name 3        3
#  4     2 Name 1        1
#  5     2 Name 2        2
#  6     3 Name 1        1
#  7     3 Name 2        2
#  8     3 Name 3        3
#  9     3 Name 4        4
# 10     3 Name 5        5

Введение id во фрейм обходит ожидание tidyr::spread, что есть два столбца, один для сохранения и одинраспространять.Он также (для вашего случая) служит возможностью повторного объединения авторов с исходными данными.Если есть лучший столбец, который уникально идентифицирует каждую строку / публикацию, используйте это вместо этого.Если у вас нет более подходящих полей, то, возможно, было бы лучше добавить их до начала этого процесса, поэтому «убедитесь», что исходные данные и эти удлиненные данные имеют идентичные идентификаторы, возможно, с:

x <- mutate(x, id = row_number())
# or with base
x$id <- seq_len(nrow(x))

Данные:

x <- read.csv(header=TRUE, stringsAsFactors=FALSE, text="
authors, pubtitle, title, date
Name 1; Name 2; Name 3, Journal Title, Article Title, 2018
Name 1; Name 2, Journal Title, Article Title, 2019
Name 1; Name 2; Name 3; Name 4; Name 5, Journal Title, Article Title, 2018")
...