Bekerja dengan bingkai data yang mirip dengan ini:
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
Saya mencoba menambahkan kolom dengan penomoran dalam setiap grup. Melakukannya dengan cara ini jelas tidak menggunakan kekuatan R:
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
Apa cara yang baik untuk melakukan ini?
Jawaban:
Gunakan
ave
,ddply
,dplyr
ataudata.table
:atau:
atau:
atau (memori paling efisien, karena diberikan oleh referensi di dalam
DT
):sumber
ave
memberikan pelampung bukan int di sini. Bergantian, bisa berubahdf$val
menjadiseq_len(nrow(df))
. Saya baru saja menemukan ini di sini: stackoverflow.com/questions/42796857/…data.table
solusi ini tampaknya lebih cepat daripada menggunakanfrank
: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
solusi yang baik. Tetapi jika, seperti saya, Anda terus mendapatkan kesalahan aneh ketika mencoba pendekatan ini, pastikan bahwa Anda tidak mendapatkan konflik di antaraplyr
dandplyr
seperti yang dijelaskan dalam posting ini. Hal ini dapat dihindari dengan menelepon secara eksplisitdplyr::mutate(...)
data.table
Metode lain adalahsetDT(df)[, id:=rleid(val), by=.(cat)]
library(plyr)
danlibrary(dplyr)
menjawab untuk membuat kolom val peringkat dalam urutan menurun?Untuk membuat ini r-faqpertanyaan lebih lengkap, alternatif R dasar dengan
sequence
danrle
:yang memberikan hasil yang diinginkan:
Jika
df$cat
merupakan variabel faktor, Anda harus membungkusnyaas.character
terlebih dahulu:sumber
cat
kolom untuk diurutkan?cat
Berikut adalah opsi menggunakan
for
loop oleh grup bukan oleh baris (seperti OP lakukan)sumber
Berikut ini adalah trik perbaikan kecil yang memungkinkan sort 'val' di dalam grup:
sumber
Saya ingin menambahkan
data.table
varian menggunakanrank()
fungsi yang memberikan kemungkinan tambahan untuk mengubah urutan dan dengan demikian membuatnya sedikit lebih fleksibel daripadaseq_len()
solusi dan sangat mirip dengan fungsi row_number di RDBMS.sumber
dplyr
Kemungkinan lain bisa:sumber
1:n()
menggunakanseq_len(n())
lebih aman, jika dalam urutan operasi Anda memiliki situasi di manan()
mungkin kembali0
, karena1:0
memberi Anda panjang dua vektor sementaraseq_len(0)
memberikan panjang vektor nol, sehingga menghindari kesalahan panjang ketidakcocokan denganmutate()
.Menggunakan
rowid()
fungsi didata.table
:sumber