Arbeiten mit einem ähnlichen Datenrahmen:
set.seed(100)
df <- data.frame(cat = c(rep("aaa", 5), rep("bbb", 5), rep("ccc", 5)), val = runif(15))
df <- df[order(df$cat, df$val), ]
df
cat val
1 aaa 0.05638315
2 aaa 0.25767250
3 aaa 0.30776611
4 aaa 0.46854928
5 aaa 0.55232243
6 bbb 0.17026205
7 bbb 0.37032054
8 bbb 0.48377074
9 bbb 0.54655860
10 bbb 0.81240262
11 ccc 0.28035384
12 ccc 0.39848790
13 ccc 0.62499648
14 ccc 0.76255108
15 ccc 0.88216552
Ich versuche, innerhalb jeder Gruppe eine Spalte mit Nummerierung hinzuzufügen. Wenn Sie dies auf diese Weise tun, werden die Kräfte von R offensichtlich nicht genutzt:
df$num <- 1
for (i in 2:(length(df[,1]))) {
if (df[i,"cat"]==df[(i-1),"cat"]) {
df[i,"num"]<-df[i-1,"num"]+1
}
}
df
cat val num
1 aaa 0.05638315 1
2 aaa 0.25767250 2
3 aaa 0.30776611 3
4 aaa 0.46854928 4
5 aaa 0.55232243 5
6 bbb 0.17026205 1
7 bbb 0.37032054 2
8 bbb 0.48377074 3
9 bbb 0.54655860 4
10 bbb 0.81240262 5
11 ccc 0.28035384 1
12 ccc 0.39848790 2
13 ccc 0.62499648 3
14 ccc 0.76255108 4
15 ccc 0.88216552 5
Was wäre ein guter Weg, um dies zu tun?
Antworten:
Verwenden Sie
ave
,ddply
,dplyr
oderdata.table
:oder:
oder:
oder (der speichereffizienteste, da er durch Bezugnahme innerhalb zugewiesen wird
DT
):quelle
ave
ein Float anstelle eines Int angegeben wird. Alternativ könnte, änderndf$val
zuseq_len(nrow(df))
. Ich bin gerade hier drüben darauf gestoßendata.table
scheint diese Lösung schneller zu sein als die Verwendung vonfrank
:library(microbenchmark); microbenchmark(a = DT[, .(val ,num = frank(val)), by = list(cat)] ,b =DT[, .(val , id = seq_len(.N)), by = list(cat)] , times = 1000L)
dplyr
Lösung ist gut. Aber wenn Sie, wie ich, immer wieder seltsame Fehler bekommen, wenn Sie diesen Ansatz ausprobieren, stellen Sie sicher, dass Sie keine Konflikte zwischenplyr
unddplyr
wie in diesem Beitrag erklärt bekommen. Dies kann vermieden werden, indem Sie explizitdplyr::mutate(...)
data.table
Methode istsetDT(df)[, id:=rleid(val), by=.(cat)]
library(plyr)
undlibrary(dplyr)
beantworte ich, um die Spalte mit dem Rangwert in absteigender Reihenfolge zu erstellen?Dafür r-faqFrage vollständiger, eine Basis-R-Alternative mit
sequence
undrle
:was das beabsichtigte Ergebnis ergibt:
Wenn
df$cat
es sich um eine Faktorvariable handelt, müssen Sie sieas.character
zuerst einschließen :quelle
cat
Spalte sortiert wird?cat
Hier ist eine Option, bei der eine
for
Schleife nach Gruppen und nicht nach Zeilen verwendet wird (wie bei OP).quelle
Hier ist ein kleiner Verbesserungstrick, mit dem 'val' innerhalb der Gruppen sortiert werden kann:
quelle
Ich möchte eine
data.table
Variante mit derrank()
Funktion hinzufügen , die die zusätzliche Möglichkeit bietet, die Reihenfolge zu ändern, sie also etwas flexibler als dieseq_len()
Lösung macht und den Funktionen row_number in RDBMS ziemlich ähnlich ist.quelle
Eine andere
dplyr
Möglichkeit könnte sein:quelle
1:n()
Verwendungseq_len(n())
sicherer, wenn Sie in Ihrer Abfolge von Operationen eine Situation haben, in der Sien()
möglicherweise zurückkehren0
, da1:0
Sie einen Vektor mit einer Länge von zwei und einen Vektor mitseq_len(0)
einer Länge von Null erhalten, wodurch ein Längeninkongruenzfehler mit vermieden wirdmutate()
.Verwenden der
rowid()
Funktion indata.table
:quelle