Как объединить два кадра данных с конфликтующими значениями - PullRequest
0 голосов
/ 02 февраля 2019

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


Я прочитал CSV-файл в таблицу.Там я имею дело с 3 столбцами: «ID» (идентификатор автора), «num_pub» (количество опубликованных статей) и «год» (охватывает период с 1930 по 2017 год).

Я хотел бы получитьфинальная таблица, где у меня будет "num_pub" для каждого "года", для каждого "ID".Таким образом, строки будут «ID», столбцы - «год», а под каждым годом будет соответствующее значение «num_pub» или 0, если автор ничего не опубликовал.


Я попытался создать две новые таблицы и объединить их несколькими различными способами, описанными здесь , но безрезультатно.


Итак, сначала я прочитал свой файл в таблицу: tab<-read.table("mytable.csv",sep=",",head=T,colClasses=c("character","numeric","factor"))

head(tab,10) ID num_pub year 1 00002 1 1977 2 00002 2 1978 3 00002 1 1983 4 00002 4 1984 5 00002 3 1990 6 00002 1 1994 7 00002 2 1996 8 00004 3 1957 9 00004 1 1958 10 00004 1 1959

После этого я смог создать таблицу, в которой для каждого «идентификатора» был каждый отдельный «год», и если автор опубликовал в этом году,значение было 1, в противном случае это было 0: a<-table(tab[,1], tab[,3])

Вызов head(a,1) возвращает следующую таблицу: pic


Я хотел бы знать, какДля достижения желаемого результата я описал выше.А именно, имея таблицу, в которой строки будут заполняться "ID", столбцы будут заполняться "year" (с 1930 по 2017), а под каждым годом будет фактическое значение "num_pub" или значение 0,Структура таблицы будет такой же, как показано на pic

Спасибо за ваше время и помощь.Я очень плохо знаком с R, и вроде как застрял в грязи с этим.

Редактировать: изменение формы, как объяснено здесь , не решает мою проблему.Мне нужны нули вместо "NA", и я хочу, чтобы мой год начинался с 1930 года, а не с первого года, который опубликовал автор.

Ответы [ 3 ]

0 голосов
/ 02 февраля 2019

В базе R это может быть обработано операцией слияния, за которой следует некоторое приведение к 0/1 путем отрицания is.na и использования as.numeric.(Правда, функция complete выглядит проще.

temp <-  merge(expand.grid(ID=sprintf("%05d", 2:4),year=1930:2018), tab, all=T) 
str(temp)
#--------
'data.frame':   267 obs. of  3 variables:
 $ ID     : Factor w/ 3 levels "00002","00003",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ year   : int  1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 ...
 $ num_pub: num  NA NA NA NA NA NA NA NA NA NA ...

 temp$any_pub <- as.numeric(!is.na(temp$num_pub))

 head(temp)
     ID year num_pub any_pub
1 00002 1930      NA       0
2 00002 1931      NA       0
3 00002 1932      NA       0
4 00002 1933      NA       0
5 00002 1934      NA       0
6 00002 1935      NA       0

tapply(temp$any_pub, temp$ID,sum)
#
00002 00003 00004 
    7     0     3 
0 голосов
/ 03 февраля 2019

, используя reshape2 & dcast, можно перейти к широкоформатному формату, а затем выполнить конвейер, чтобы заменить NA s на 0 с.

library(reshape2)
library(dplyr)

dcast(tab, ID~year, value.var = "num_pub") %>% 
  replace(is.na(.), 0)

     ID 1957 1958 1959 1977 1978 1983 1984 1990 1994 1996
1 00002    0    0    0    1    2    1    4    3    1    2
2 00004    3    1    1    0    0    0    0    0    0    0
0 голосов
/ 02 февраля 2019

Вы можете использовать complete, чтобы заполнить нули для недоступных данных, а затем spread, чтобы превратить ваш столбец лет в несколько столбцов (оба из пакета tidyr):

library(tidyr)

df_complete <-
  complete(df, ID, year, fill = list(num_pub = 0))

spread(df_complete, key = year, value = num_pub)

# A tibble: 2 x 11
  ID    `1957` `1958` `1959` `1977` `1978` `1983` `1984` `1990` `1994` `1996`
  <fct>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
1 00002      0      0      0      1      2      1      4      3      1      2
2 00004      3      1      1      0      0      0      0      0      0      0

Данные:

df <-
  data.frame(ID = c("00002", "00002", "00002", "00002", "00002", "00002", "00002", "00004", "00004", "00004"),
             num_pub = c(1, 2, 1, 4, 3, 1, 2, 3, 1, 1),
             year = c(1977, 1978, 1983, 1984, 1990, 1994, 1996, 1957, 1958, 1959))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...