2016-07-29 26 views
0

Ich versuche etwas zu lösen, das für mich seit ein paar Tagen ein Problem ist.Spalte zu Dataframe abhängig von bestimmten Zeilenwerten hinzufügen

Hier ein Beispiel meines data.frame, von dem ich hoffe, dass er mit meinem echten funktioniert.

df <- read.table(text = 'ID Day Count 
    33012 9526 4 
    35004 9526 4 
    37006 9526 4 
    37008 9526 4 
    21009 1913 3 
    24005 1913 3 
    25009 1913 3 
    22317 2286 2 
    37612 2286 2 
    25009 14329 1 
    48007 9525 0 
    88662 9524 0 
    1845 9524 0 
    8872 2285 0 
    49002 1912 0 
    1664 1911 0', header = TRUE) 

Ich brauche eine neue Spalte (new_col) meinen data.frame hinzuzufügen, die Werte von 1 bis 4 enthält Diese new_col Werte enthalten müssen, jeden Tag (x) Tag (x -1) und Tag (x -2), wobei x = 9526, 1913, 2286, 14329 (Spalte Day).

sollte Meine Ausgabe die folgende sein:

ID Day Count new_col 
33012 9526 4  1 
35004 9526 4  1 
37006 9526 4  1 
37008 9526 4  1 
21009 1913 3  2 
24005 1913 3  2 
25009 1913 3  2 
22317 2286 2  3 
37612 2286 2  3 
25009 14329 1  4 
48007 9525 0  1 
88662 9524 0  1 
1845 9524 0  1 
8872 2285 0  3 
49002 1912 0  2 
1664 1911 0  2 

Die data.frame von new_col dann bestellt werden:

ID Day Count new_col 
33012 9526 4  1 
35004 9526 4  1 
37006 9526 4  1 
37008 9526 4  1 
48007 9525 0  1 
88662 9524 0  1 
1845 9524 0  1 
21009 1913 3  2 
24005 1913 3  2 
25009 1913 3  2 
49002 1912 0  2 
1664 1911 0  2 
22317 2286 2  3 
37612 2286 2  3 
8872 2285 0  3 
25009 14329 1  4 

Mein richtiger data.frame ist komplexer als das Beispiel (dh mehr Spalten und mehr Werte in der Count Spalte, daher geduldig sein, wenn ich die Frage aktualisieren werde.

Jeder Vorschlag wird wirklich hilfreich sein.

Antwort

1

Ich bin nicht sicher, ob ich völlig verstehe Ihre Frage, aber es scheint, wie Sie cut() dies zu erreichen, verwenden könnte, wie folgt:

x <- c(1913, 2286, 9526, 14329) 
df$new_col <- cut(df$Day, c(-Inf, x, Inf)) 
df$new_col <- as.numeric(factor(df$new_col, levels=unique(df$new_col))) 
+0

ich geben würde 1'000 Punkte, wenn nur ich könnte. Danke :) Ihr Code funktioniert nicht nur mit x, x-1 und x-2, sondern mit allen Tagen vor x (vielleicht aufgrund der Tatsache von c (-Inf, x, Inf)). anyway..thanks nochmal –

+0

hi, ich habe gerade eine sehr ähnliche Frage http://StackOverflow.com/Questions/38847645/add-column-to-Dataframe-depending-on-specific-row-values-2 geschrieben, die Sie vielleicht können antworte leicht. danke –

0

Hier ist eine nicht skalierbar, aber leicht zu verstehen Lösung mit dplyr Paket wir können case_when rekodieren den Tag auf der Grundlage der Bedingung verwenden:

library(dplyr) 
df %>% mutate(new_col = case_when(abs(df$Day - 9526) <= 2 ~ 1, 
            abs(df$Day - 1913) <= 2 ~ 2, 
            abs(df$Day - 2286)<= 2 ~ 3, 
            abs(df$Day - 14329) <= 2 ~ 4)) %>% 
    arrange(new_col) 

#  ID Day Count new_col 
# 1 33012 9526  4  1 
# 2 35004 9526  4  1 
# 3 37006 9526  4  1 
# 4 37008 9526  4  1 
# 5 48007 9525  0  1 
# 6 88662 9524  0  1 
# 7 1845 9524  0  1 
# 8 21009 1913  3  2 
# 9 24005 1913  3  2 
# 10 25009 1913  3  2 
# 11 49002 1912  0  2 
# 12 1664 1911  0  2 
# 13 22317 2286  2  3 
# 14 37612 2286  2  3 
# 15 8872 2285  0  3 
# 16 25009 14329  1  4 

ein skalierbarer Ansatz zu verwenden foverlaps von data.table Paket sein würde, wo wir eine Nachschlagetabelle vorbereiten und dann mit dem Original-Tisch sitzt zurück und verwenden within Art verbindet die Tage, um sicherzustellen, sind in dem angegebenen Bereich in der Nachschlagetabelle, für eine bessere Erklärung über foverlaps

library(data.table) 
# prepare the look up table 
x <- c(9526, 1913, 2286, 14329) 
dt1 <- data.table(start = x - 2, end = x, new_col = 1:4) 
setkey(dt1) 
dt1 
# start end new_col 
# 1: 1911 1913  2 
# 2: 2284 2286  3 
# 3: 9524 9526  1 
# 4: 14327 14329  4 

# prepare the original table 
dt = copy(setDT(df)) 
dt[, Day2 := Day] 

# do a foverlaps 
foverlaps(dt, dt1, by.x = c("Day", "Day2"), by.y = c("start", "end"), type = "within", mult = "all", nomatch = 0L)[, .(ID, Day, Count, new_col)][order(new_col)] 

#  ID Day Count new_col 
# 1 33012 9526  4  1 
# 2 35004 9526  4  1 
# 3 37006 9526  4  1 
# 4 37008 9526  4  1 
# 5 48007 9525  0  1 
# 6 88662 9524  0  1 
# 7 1845 9524  0  1 
# 8 21009 1913  3  2 
# 9 24005 1913  3  2 
# 10 25009 1913  3  2 
# 11 49002 1912  0  2 
# 12 1664 1911  0  2 
# 13 22317 2286  2  3 
# 14 37612 2286  2  3 
# 15 8872 2285  0  3 
# 16 25009 14329  1  4 
+0

hi, dein code funktioniert perfekt mit dem beispiel, aber nicht mit meinem echten datenframe und das macht mich wirklich frustriert –