Извлечение данных из разных столбцов во фрейме данных на основе значений строк - PullRequest
0 голосов
/ 21 марта 2020

Из каждой строки во фрейме данных, df, я хочу извлечь значения в столбцах, как описано ниже, и создать новый фрейм данных, вывод.

Когда Year равен 2003, мне нужны значения в Столбцы Y_2001 и Y_2002 в кадре выходных данных как Год 1 и Год 2. Это значения, соответствующие двум годам, предшествующим году, указанному в столбце Год. Точно так же, если год равен 2006 году, мне нужны значения в Y_2004 и Y_2005 в кадре выходных данных. Аналогично, за все годы в колонке Год.

> df
     ID Year Y_2001 Y_2002 Y_2003 Y_2004 Y_2005
[1,]  1 2003      2      4      6      4      3
[2,]  2 2004      5      9      7      1      2
[3,]  3 2006      4      3      5      7      8
[4,]  4 2004      7      6      4      8      9

> output
     ID Year Year1 Year2
[1,]  1 2003     2     4
[2,]  2 2004     9     7
[3,]  3 2006     7     8
[4,]  4 2004     6     4

Может кто-нибудь помочь мне создать код, чтобы получить вывод выше? Высоко ценю любую поддержку.

Ответы [ 3 ]

2 голосов
/ 21 марта 2020

Вот решение tidyverse:

Примет данные и переведет их в длинную форму с pivot_longer. Интересующие значения данных - это когда год "строка" на 1 или 2 года меньше года "столбца". Вы можете filter для этих различий (filter здесь явно для разниц в 1 или 2 года).

Дополнительный столбец создается с mutate для имен столбцов Year1 и Year2 (примечание Year1 - это разница в 2 года, а Year2 - это разница в 1 год, поэтому для этого обращения значения вычитаются из 3). Наконец, pivot_wider возвращает данные в широкой форме.

library(tidyverse)

df %>%
  pivot_longer(cols = -c(ID, Year), names_to = c(".value", "Year_Sep"), names_sep = "_", names_ptypes = list(Year_Sep = numeric())) %>%
  filter(Year - Year_Sep == 1 | Year - Year_Sep == 2) %>%
  mutate(YearCol = paste0("Year", 3 - (Year - Year_Sep))) %>%
  pivot_wider(id_cols = c(ID, Year), names_from = YearCol, values_from = Y)

Вывод

# A tibble: 4 x 4
     ID  Year Year1 Year2
  <int> <int> <int> <int>
1     1  2003     2     4
2     2  2004     9     7
3     3  2006     7     8
4     4  2004     6     4
1 голос
/ 21 марта 2020

Немного неуклюжего решения, но ...

i.col <- function(data, n) { # Returns the column index corresponding to the year
  sapply(data$Year-n, function(x) grep(x, names(data)))
}

df$Year1 <- diag(as.matrix(df[, i.col(df, n=2)]))
df$Year2 <- diag(as.matrix(df[, i.col(df, n=1)]))

Редактировать : Очевидно, использование diag очень медленно . Использование cbind для доступа к элементам матрицы является предпочтительным.

df$Year1 <- df[cbind(1:4, i.col(df, n=2))] # where 4 is number of rows
df$Year2 <- df[cbind(1:4, i.col(df, n=1))]

df
  ID Year Y_2001 Y_2002 Y_2003 Y_2004 Y_2005 Year1 Year2
1  1 2003      2      4      6      4      3     2     4
2  2 2004      5      9      7      1      2     9     7
3  3 2006      4      3      5      7      8     7     8
4  4 2004      7      6      4      8      9     6     4
0 голосов
/ 21 марта 2020

Вот один способ с построчным apply, при условии, что вы можете узнать начальный год (2001).

cbind(df[1:2], t(apply(df[-1], 1, function(x) 
               { vals <- x[1] - 2001; x[c(vals:(vals + 1))]})))

#  ID Year 1 2
#1  1 2003 2 4
#2  2 2004 9 7
#3  3 2006 7 8
#4  4 2004 6 4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...