Mam następujący 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

Teraz chcę teraz, aby chciałbym przenieść tylko obserwacje z kolumn {X0}} i C2 do jednego C2 przez jeden rząd, jeśli następny rząd jest rok w przyszłości z bieżącego roku rzędu.

W tym przykładzie: przesuń wartość z wiersza 1 do wiersza 2. Więc nadpisuj wartość z rzędu 2. ROW4 oznacza wartości dla V2 i C2 i C2, ponieważ nie ma 2004. Dla B: obserwacje W wierszu 7 Uzyskaj wartości z rzędu 6, a wartości z rzędu 7 znikają, ponieważ zaczyna się nowa litera w nazwie kolumny. Zrób to dla każdej litery.

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

Czy istnieje sposób na to? :)

Dziękuję Ci :)

0
bli12blu12 4 czerwiec 2018, 00:58

4 odpowiedzi

Najlepsza odpowiedź

Możemy zbudować klucz pomocnika do zmiany

#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 
1
YOBEN_S 3 czerwiec 2018, 23:04

Możesz użyć funkcji shift z pakietu 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
0
Bulat 3 czerwiec 2018, 22:42

Zakładając, że kolumna KeyC dokładnie koduje wszystkie przypadki, które chcesz skopiować:

#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
Esther 4 czerwiec 2018, 01:16

Za pomocą

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

Możesz także użyć

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
Onyambu 4 czerwiec 2018, 01:56