Переместить строки из определенных столбцов, если следующие наблюдения отличаются на 1 год - PullRequest
0 голосов
/ 04 июня 2018

Я получил следующее df:

Name   Year  [Columns which rows should not be moved]  V2  C2   KeyC
A      2001       ...                                   4   7    NA
A      2002       ...                                   2   0.5   1
A      2003       ...                                   4   0.2   0
A      2005       ...                                   3   0.3   NA
B      2004       ...                                   0   0.4   NA
B      2006       ...                                   1   7     NA
B      2007       ...                                   2   0.6   1
C      2002       ....                                  4     4    NA

Что я хочу сделать сейчас, так это то, что я хочу переместить ТОЛЬКО наблюдения из столбцов V2 и C2 на одну строку, если следующая строкаэто один год в будущем из строки текущего года.

В этом примере: переместите значение из строки 1 в строку 2. Поэтому перезапишите значение из строки 2. В строке 4 сохраняются значения для V2 иC2, поскольку нет 2004. Для B: наблюдения в строке 7 получают значения из строки 6, а значения из строки 7 исчезают, когда в столбце Имя начинается новая буква.Делайте это для каждой буквы.

Name   Year  [Columns which rows should not be moved]  V2  C2    KeyC
A      2001       ...                                   4    7     NA
A      2002       ...                                   4    7      1
A      2003       ...                                   2   0.5     0
A      2005       ...                                   3   0.3    NA
B      2004       ...                                   0   0.4    NA
B      2006       ...                                   1     7    NA
B      2007       ...                                   1     7     1
C      2002       ....                                  4     4    NA

Есть ли способ сделать это?:)

Спасибо:)

Ответы [ 4 ]

0 голосов
/ 04 июня 2018

с использованием

library(tidyverse)
dt%>%
  group_by(name)%>%
  mutate_at(vars(C2,V2),funs(ifelse(c(0,diff(year))==1,lag(.),.)))
# A tibble: 8 x 6
# Groups:   name [3]
  name   year x        V2    C2  KeyC
  <fct> <int> <fct> <int> <dbl> <int>
1 A      2001 ...       4 7.00     NA
2 A      2002 ...       4 7.00      1
3 A      2003 ...       2 0.500     0
4 A      2005 ...       3 0.300    NA
5 B      2004 ...       0 0.400    NA
6 B      2006 ...       1 7.00     NA
7 B      2007 ...       1 7.00      1
8 C      2002 ....      4 4.00     NA

Вы также можете использовать

library(data.table)
setDT(dt)[,c("C2","V2") := lapply(.SD,function(x)ifelse(c(0,diff(year))==1,shift(x),x)),by=name, .SDcols=c("C2","V2")]
dt
   name year    x V2  C2 KeyC
1:    A 2001  ...  4 7.0   NA
2:    A 2002  ...  4 7.0    1
3:    A 2003  ...  2 0.5    0
4:    A 2005  ...  3 0.3   NA
5:    B 2004  ...  0 0.4   NA
6:    B 2006  ...  1 7.0   NA
7:    B 2007  ...  1 7.0    1
8:    C 2002 ....  4 4.0   NA
0 голосов
/ 04 июня 2018

Мы можем построить вспомогательную клавишу для сигнала на сдвиг

#library(data.table)
dt=data.table(dt)
dt[, KEY:=c(0L,diff(year)), by=name]

dt[dt$KEY==1,c('V2','C2')]=data.table(apply(dt[,c('V2','C2')],2,shift)[dt$KEY==1,])
dt
name year    x V2  C2 KeyC KEY
1:    A 2001  ...  4 7.0   NA   0
2:    A 2002  ...  4 7.0    1   1
3:    A 2003  ...  2 0.5    0   1
4:    A 2005  ...  3 0.3   NA   2
5:    B 2004  ...  0 0.4   NA   0
6:    B 2006  ...  1 7.0   NA   2
7:    B 2007  ...  1 7.0    1   1
8:    C 2002 ....  4 4.0   NA   0 
0 голосов
/ 04 июня 2018

Предполагая, что столбец KeyC точно кодирует все случаи, которые вы хотите скопировать:

#make helper rows that are offset by 1
df$V2_help<-c(NA, df$V2[1:nrow(df)-1])
df$C2_help<-c(NA, df$C2[1:nrow(df)-1])

#use ifelse statement to replace data where KeyC is not NA
df$V2<-ifelse(!is.na(df$KeyC), df$V2_help, df$V2)
df$C2<-ifelse(!is.na(df$KeyC), df$C2_help, df$C2)

#remove helper columns
df<-df[,setdiff(colnames(df), c("V2_help", "C2_help"))]

 Name Year V2  C2 KeyC
1    A 2001  4 7.0   NA
2    A 2002  4 7.0    1
3    A 2003  2 0.5    0
4    A 2005  3 0.3   NA
5    B 2004  0 0.4   NA
6    B 2006  1 7.0   NA
7    B 2007  1 7.0    1
8    C 2002  4 4.0   NA
0 голосов
/ 04 июня 2018

Вы можете использовать функцию shift из пакета data.table:

dt <- read.table(text = "name   year  x  V2  C2   KeyC
A      2001       ...                                   4   7    NA
A      2002       ...                                   2   0.5   1
A      2003       ...                                   4   0.2   0
A      2005       ...                                   3   0.3   NA
B      2004       ...                                   0   0.4   NA
B      2006       ...                                   1   7     NA
B      2007       ...                                   2   0.6   1
C      2002       ....                                  4     4    NA",
header = T)

library(data.table)
dt <- data.table(dt)
dt[, `:=` (previous.year = shift(year),
           previous.V2 = shift(V2),
           previous.C2 = shift(C2))]
dt[, has.previous.year := year - 1 == previous.year]
dt[has.previous.year == TRUE, 
   `:=` (V2 = previous.V2, 
         C2 = previous.C2)]
dt <- dt[, .(name, year, x, V2, C2, KeyC)]
dt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...