манипулировать данными с несколькими значениями в ячейке в г - PullRequest
0 голосов
/ 29 февраля 2020

У меня есть набор данных, похожий на

universityies <- c("UNI.1;UNI.1;UNI.2;UNI.3","UNI.5", "UNI.3;UNI.4"  )
papers <- c(1,1,1)
cited <- c(10,5,20)

df <- data.frame(universityies, papers, cited )
df

, и я хочу получить что-то вроде

       #total papers  total cited
#UNI.1   1              10  
#UNI.2   1              10 
#UNI.3   2              30
#UNI.4   1              20
#UNI.5   1              5

большое спасибо заранее,

Ответы [ 3 ]

2 голосов
/ 29 февраля 2020

Мы можем разделить данные на ";", получить уникальные строки, group_by universityies подсчитать различные статьи и общее количество ссылок.

library(dplyr)

df %>%
  mutate(row = row_number()) %>%
  tidyr::separate_rows(universityies, sep = ";") %>%
  distinct() %>%
  group_by(universityies) %>%
  summarise(total_papers = n_distinct(row), 
            total_cited = sum(cited))

#  universityies total_papers total_cited
#  <chr>                <int>       <dbl>
#1 UNI.1                    1          10
#2 UNI.2                    1          10
#3 UNI.3                    2          30
#4 UNI.4                    1          20
#5 UNI.5                    1           5
1 голос
/ 29 февраля 2020

Мы можем использовать cSplit из splitstackshape и data.table методы

library(data.table)
library(splitstackshape)
unique(cSplit(setDT(df, keep.rownames = TRUE),  "universityies", ";", 
 "long"))[, .(total_papers = uniqueN(rn), total_cited = sum(cited)),.(universityies)]
#   universityies total_papers total_cited
#1:         UNI.1            1          10
#2:         UNI.2            1          10
#3:         UNI.3            2          30
#4:         UNI.5            1           5
#5:         UNI.4            1          20
1 голос
/ 29 февраля 2020

Вы можете использовать strsplit на первом шаге, затем aggregate

tmp <- do.call(rbind, apply(df, 1, function(x) 
  setNames(data.frame(strsplit(x[1], ";"), as.numeric(x[2]), as.numeric(x[3]), 
                      row.names=NULL, stringsAsFactors=FALSE), names(df))))
res <- aggregate(cbind(total.papers=papers, total.cited=cited) ~ universityies, 
                 unique(tmp), sum)
res[order(res$universityies), ]
#   universityies total.papers total.cited
# 1         UNI.1            1          10
# 2         UNI.2            1          10
# 3         UNI.3            2          30
# 4         UNI.4            1          20
# 5         UNI.5            1           5
...