Ma'lumotlar to'plamini taqsimlash

Quyidagi ma'lumotlar to'plami bilan:

  id from to trip
1  1    A  B 
2  1    B  C    X
3  1    C  D 
4  1    D  A    X
5  2    B  A    X
6  2    A  C 
7  2    C  D 

Men sayohat ustuniga X ga etib borganimda, shunga o'xshash biror narsani olish uchun ma'lumotni ajratishga harakat qilaman (yangi ustun borligini unutmang):

  id from to trip group
1  1    A  B   1
2  1    B  C    X  1
3  1    C  D   2
4  1    D  A    X  2
5  2    B  A    X  3
6  2    A  C   4
7  2    C  D   4

Bu degani, kuzatuvlar/satrlar orqali o'tadi va id va sayohatlar ustuniga asoslangan holda har safar X ga yetganda yangi raqamni boshlaydi.

group_by (df, id, trip) bilan bir nechta narsani sinab ko'rdim, lekin men har doim ham shunga o'xshash strukturasisiz tugamasman.

Har qanday taklif bormi?

1
mutate (df, cumsum (! is.na (safar))) ? Yoki faqat group_by (df, cumsum (! Is.na (safar)))
qo'shib qo'ydi muallif Axeman, manba
mutate (df, cumsum (! is.na (safar))) ? Yoki faqat group_by (df, cumsum (! Is.na (safar)))
qo'shib qo'ydi muallif Axeman, manba
@FilipeTeixeira lag qo'shing.
qo'shib qo'ydi muallif Axeman, manba
@FilipeTeixeira lag qo'shing.
qo'shib qo'ydi muallif Axeman, manba
Primitual yechim, lekin amalga oshirish oson.
qo'shib qo'ydi muallif Lowpar, manba
Primitual yechim, lekin amalga oshirish oson.
qo'shib qo'ydi muallif Lowpar, manba
Sizda qancha qatorni kutish kerak bo'lsa, har doim x mavjud bo'lganida avtomatik ravishda oshiriladigan yangi o'zgaruvchi yaratishingiz mumkin.
qo'shib qo'ydi muallif Lowpar, manba
@Axeman nafaqat qiziquvchanlikdan, agar mutanosiblik funktsiyasi o'rniga NA qiymati o'rniga kosmik faktorga ega bo'lar edi? Menda bu mutate (travel_by, trip_id = c (1, bosh (cumsum (+ = "X")) +1, -1)) ga ega, lekin ishonchim komil emas. yana oqlangan narsa.
qo'shib qo'ydi muallif FilipeTeixeira, manba
@Axeman nafaqat qiziquvchanlikdan, agar mutanosiblik funktsiyasi o'rniga NA qiymati o'rniga kosmik faktorga ega bo'lar edi? Menda bu mutate (travel_by, trip_id = c (1, bosh (cumsum (+ = "X")) +1, -1)) ga ega, lekin ishonchim komil emas. yana oqlangan narsa.
qo'shib qo'ydi muallif FilipeTeixeira, manba
@Axeman nafaqat qiziquvchanlikdan, agar mutanosiblik funktsiyasi o'rniga NA qiymati o'rniga kosmik faktorga ega bo'lar edi? Menda bu mutate (travel_by, trip_id = c (1, bosh (cumsum (+ = "X")) +1, -1)) ga ega, lekin ishonchim komil emas. yana oqlangan narsa.
qo'shib qo'ydi muallif FilipeTeixeira, manba
@Axeman mukammal ishlaydi. Hech narsadan ko'ra yaxshiroq hisoblash uchun hali ancha vaqt talab etiladi. Hech bo'lmasa, mening hisobim bor.
qo'shib qo'ydi muallif FilipeTeixeira, manba
@Axeman mukammal ishlaydi. Hech narsadan ko'ra yaxshiroq hisoblash uchun hali ancha vaqt talab etiladi. Hech bo'lmasa, mening hisobim bor.
qo'shib qo'ydi muallif FilipeTeixeira, manba
@Axeman mukammal ishlaydi. Hech narsadan ko'ra yaxshiroq hisoblash uchun hali ancha vaqt talab etiladi. Hech bo'lmasa, mening hisobim bor.
qo'shib qo'ydi muallif FilipeTeixeira, manba
@Axeman, men buni ham sinab ko'rdim, lekin nima bo'lishidan qat'iy nazar, bu X sonini ko'paytirganda, aslida undan keyin bo'lishi kerak bo'lsa, u yangi sonni oshiradi. X topib olishning ma'nosi avvalgi qatorga o'xshash sonni berishi kerak.
qo'shib qo'ydi muallif FilipeTeixeira, manba
@Axeman, men buni ham sinab ko'rdim, lekin nima bo'lishidan qat'iy nazar, bu X sonini ko'paytirganda, aslida undan keyin bo'lishi kerak bo'lsa, u yangi sonni oshiradi. X topib olishning ma'nosi avvalgi qatorga o'xshash sonni berishi kerak.
qo'shib qo'ydi muallif FilipeTeixeira, manba
@Axeman, men buni ham sinab ko'rdim, lekin nima bo'lishidan qat'iy nazar, bu X sonini ko'paytirganda, aslida undan keyin bo'lishi kerak bo'lsa, u yangi sonni oshiradi. X topib olishning ma'nosi avvalgi qatorga o'xshash sonni berishi kerak.
qo'shib qo'ydi muallif FilipeTeixeira, manba
@Lowpar, bu misolda oddiy, lekin haqiqiy hayotimda 9.000.000 kuzatishlarim bor, bu esa asosiy yondashuvni qabul qilishni murakkablashtiradi. Va siz aytayotgan narsa agar funktsiyasi bilan ishlaydi?
qo'shib qo'ydi muallif FilipeTeixeira, manba
@Lowpar, bu misolda oddiy, lekin haqiqiy hayotimda 9.000.000 kuzatishlarim bor, bu esa asosiy yondashuvni qabul qilishni murakkablashtiradi. Va siz aytayotgan narsa agar funktsiyasi bilan ishlaydi?
qo'shib qo'ydi muallif FilipeTeixeira, manba

6 javoblar

Ushbu asosiy R usuli misol uchun ishlaydi:

df$group <- c(1, head(cumsum(df$trip == "X") + 1, -1))

Misolda qaytaradi

df
  id from to trip group
1  1    A  B      1
2  1    B  C    X     1
3  1    C  D      2
4  1    D  A    X     2
5  2    B  A    X     3
6  2    A  C      4
7  2    C  D      4

Bundan tashqari, birinchi kuzatish "X" bo'lsa, unda 1 birinchi element, ikkinchisi esa ikkinchi element bo'lib qoladi.

Buyruqlarda @manotheshark eslatilganidek, ushbu hal NA qiymatlari ustida ishlamaydi, chunki cumsum birinchi NA kelganidan so'ng NA ga qaytadi. Tavsiya etilgan yechim df $ trip == "X" o'rniga is.na (df $ trip) bilan almashtiriladi.

2
qo'shib qo'ydi
Safar NA sifatida saqlangan bo'lsa, bu ishlamaydi va so`ralgan matn sifatida NA ni qaytaradi. df $ group <- c (1, bosh (cumsum (! Is.na (df $ trip)) +1, -1))
qo'shib qo'ydi muallif manotheshark, manba
Aslida, bu NA ga ega bo'lish o'rniga boshqa muammolarni hal qiladi, menda omillar bor.
qo'shib qo'ydi muallif FilipeTeixeira, manba

Ushbu asosiy R usuli misol uchun ishlaydi:

df$group <- c(1, head(cumsum(df$trip == "X") + 1, -1))

Misolda qaytaradi

df
  id from to trip group
1  1    A  B      1
2  1    B  C    X     1
3  1    C  D      2
4  1    D  A    X     2
5  2    B  A    X     3
6  2    A  C      4
7  2    C  D      4

Bundan tashqari, birinchi kuzatish "X" bo'lsa, unda 1 birinchi element, ikkinchisi esa ikkinchi element bo'lib qoladi.

Buyruqlarda @manotheshark eslatilganidek, ushbu hal NA qiymatlari ustida ishlamaydi, chunki cumsum birinchi NA kelganidan so'ng NA ga qaytadi. Tavsiya etilgan yechim df $ trip == "X" o'rniga is.na (df $ trip) bilan almashtiriladi.

2
qo'shib qo'ydi
Safar NA sifatida saqlangan bo'lsa, bu ishlamaydi va so`ralgan matn sifatida NA ni qaytaradi. df $ group <- c (1, bosh (cumsum (! Is.na (df $ trip)) +1, -1))
qo'shib qo'ydi muallif manotheshark, manba
Aslida, bu NA ga ega bo'lish o'rniga boshqa muammolarni hal qiladi, menda omillar bor.
qo'shib qo'ydi muallif FilipeTeixeira, manba

Ushbu asosiy R usuli misol uchun ishlaydi:

df$group <- c(1, head(cumsum(df$trip == "X") + 1, -1))

Misolda qaytaradi

df
  id from to trip group
1  1    A  B      1
2  1    B  C    X     1
3  1    C  D      2
4  1    D  A    X     2
5  2    B  A    X     3
6  2    A  C      4
7  2    C  D      4

Bundan tashqari, birinchi kuzatish "X" bo'lsa, unda 1 birinchi element, ikkinchisi esa ikkinchi element bo'lib qoladi.

Buyruqlarda @manotheshark eslatilganidek, ushbu hal NA qiymatlari ustida ishlamaydi, chunki cumsum birinchi NA kelganidan so'ng NA ga qaytadi. Tavsiya etilgan yechim df $ trip == "X" o'rniga is.na (df $ trip) bilan almashtiriladi.

2
qo'shib qo'ydi
Safar NA sifatida saqlangan bo'lsa, bu ishlamaydi va so`ralgan matn sifatida NA ni qaytaradi. df $ group <- c (1, bosh (cumsum (! Is.na (df $ trip)) +1, -1))
qo'shib qo'ydi muallif manotheshark, manba
Aslida, bu NA ga ega bo'lish o'rniga boshqa muammolarni hal qiladi, menda omillar bor.
qo'shib qo'ydi muallif FilipeTeixeira, manba

Buni harakat qiling (agar siz aslida keyin qatorida yangi guruhni boshlashingiz kerak bo'lsa, x == "X" ga boshqa shift() bilan erishish mumkin, deb o'ylayman:

library(data.table)
set.seed(1)

na.zero <- function (x) {
  x[is.na(x)] <- 0
  return(x)
}

dt <- data.table(id = c(1,1,1,2,2,2),
                 from = sample(c("A", "B", "C", "D"), 6, replace = T),
                 to = sample(c("A", "B", "C", "D"), 6, replace = T),
                 trip = sample(c("X", NA), 6, replace = T))

dt[, group:=(cumsum(na.zero(trip=="X"))+cumsum(id-na.zero(shift(id, 1L,type = 'lag'))))]

   id from to trip group
1:  1    B  D   NA     1
2:  1    B  C    X     2
3:  1    C  C   NA     2
4:  2    D  A    X     4
5:  2    A  A   NA     4
6:  2    D  A   NA     4
0
qo'shib qo'ydi

Buni harakat qiling (agar siz aslida keyin qatorida yangi guruhni boshlashingiz kerak bo'lsa, x == "X" ga boshqa shift() bilan erishish mumkin, deb o'ylayman:

library(data.table)
set.seed(1)

na.zero <- function (x) {
  x[is.na(x)] <- 0
  return(x)
}

dt <- data.table(id = c(1,1,1,2,2,2),
                 from = sample(c("A", "B", "C", "D"), 6, replace = T),
                 to = sample(c("A", "B", "C", "D"), 6, replace = T),
                 trip = sample(c("X", NA), 6, replace = T))

dt[, group:=(cumsum(na.zero(trip=="X"))+cumsum(id-na.zero(shift(id, 1L,type = 'lag'))))]

   id from to trip group
1:  1    B  D   NA     1
2:  1    B  C    X     2
3:  1    C  C   NA     2
4:  2    D  A    X     4
5:  2    A  A   NA     4
6:  2    D  A   NA     4
0
qo'shib qo'ydi

Buni harakat qiling (agar siz aslida keyin qatorida yangi guruhni boshlashingiz kerak bo'lsa, x == "X" ga boshqa shift() bilan erishish mumkin, deb o'ylayman:

library(data.table)
set.seed(1)

na.zero <- function (x) {
  x[is.na(x)] <- 0
  return(x)
}

dt <- data.table(id = c(1,1,1,2,2,2),
                 from = sample(c("A", "B", "C", "D"), 6, replace = T),
                 to = sample(c("A", "B", "C", "D"), 6, replace = T),
                 trip = sample(c("X", NA), 6, replace = T))

dt[, group:=(cumsum(na.zero(trip=="X"))+cumsum(id-na.zero(shift(id, 1L,type = 'lag'))))]

   id from to trip group
1:  1    B  D   NA     1
2:  1    B  C    X     2
3:  1    C  C   NA     2
4:  2    D  A    X     4
5:  2    A  A   NA     4
6:  2    D  A   NA     4
0
qo'shib qo'ydi