डेटा फ़्रेम में समूहों के भीतर पंक्तियों की संख्या


163

इसी के समान डेटा फ्रेम के साथ काम करना:

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 

मैं प्रत्येक समूह के भीतर नंबरिंग के साथ एक कॉलम जोड़ने की कोशिश कर रहा हूं। इस तरह से करना स्पष्ट रूप से 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  

ऐसा करने का एक अच्छा तरीका क्या होगा?


1
मैं सवाल के शीर्षक में "seq साथ स्तरों" या "replicates
with counticates

2
@ crazysantaclaus यदि वह शीर्षक होता, तो मुझे वह नहीं मिलता, जो मैं ढूंढ रहा था :-( मैं सचमुच "एक डेटा फ्रेम में समूहों के बीच पंक्तियों की संख्या कैसे खोज रहा था"
Zimano

जवाबों:


280

का प्रयोग करें ave, ddply, dplyrया data.table:

df$num <- ave(df$val, df$cat, FUN = seq_along)

या:

library(plyr)
ddply(df, .(cat), mutate, id = seq_along(val))

या:

library(dplyr)
df %>% group_by(cat) %>% mutate(id = row_number())

या (सबसे अधिक स्मृति कुशल, क्योंकि यह संदर्भ के अनुसार प्रदान करता है DT):

library(data.table)
DT <- data.table(df)

DT[, id := seq_len(.N), by = cat]
DT[, id := rowid(cat)]

2
यह ध्यान देने योग्य हो सकता है कि aveयहां इंट के बजाय एक फ्लोट देता है। वैकल्पिक रूप से, में बदल सकता df$valहै seq_len(nrow(df))। मैं बस यहाँ इस पर भाग गया: stackoverflow.com/questions/42796857/…
फ्रैंक

1
दिलचस्प है कि यह data.tableसमाधान उपयोग करने की तुलना में तेज है frank: library(microbenchmark); microbenchmark(a = DT[, .(val ,num = frank(val)), by = list(cat)] ,b =DT[, .(val , id = seq_len(.N)), by = list(cat)] , times = 1000L)
hannes101

4
धन्यवाद! dplyrसमाधान अच्छा है। लेकिन अगर, मेरी तरह, आप इस दृष्टिकोण की कोशिश करते समय अजीब त्रुटियां करते रहे, तो सुनिश्चित करें कि आपको इस पोस्ट के बीच संघर्ष नहीं मिल रहा है plyrऔर dplyrजैसा कि इस पोस्ट में बताया गया है, इसे स्पष्ट रूप से कॉल करके टाला जा सकता हैdplyr::mutate(...)
EcologyTom

2
एक अन्य data.tableविधि हैsetDT(df)[, id:=rleid(val), by=.(cat)]
chinsoon12

अवरोही क्रम में रैंकिंग वैल कॉलम बनाने के लिए कैसे संशोधित करें library(plyr)और library(dplyr)उत्तर दें?
प्रिज़ीमस्लाव रीम जूल

26

इसे बनाने के लिए अधिक पूर्ण प्रश्न, आधार R विकल्प के साथ sequenceऔर rle:

df$num <- sequence(rle(df$cat)$lengths)

जो इच्छित परिणाम देता है:

> df
   cat        val num
4  aaa 0.05638315   1
2  aaa 0.25767250   2
1  aaa 0.30776611   3
5  aaa 0.46854928   4
3  aaa 0.55232243   5
10 bbb 0.17026205   1
8  bbb 0.37032054   2
6  bbb 0.48377074   3
9  bbb 0.54655860   4
7  bbb 0.81240262   5
13 ccc 0.28035384   1
14 ccc 0.39848790   2
11 ccc 0.62499648   3
15 ccc 0.76255108   4
12 ccc 0.88216552   5

यदि df$catएक कारक चर है, तो आपको as.characterपहले इसे लपेटने की आवश्यकता है :

df$num <- sequence(rle(as.character(df$cat))$lengths)

बस देखा, इस समाधान के लिए catस्तंभ को सॉर्ट करने की आवश्यकता है ?
zx8754

@ zx8754 हाँ, जब तक आप लगातार होने वाली संख्याओं से संख्या नहीं चाहते हैंcat
जबाप

9

यहां forपंक्तियों के बजाय समूहों द्वारा लूप का उपयोग करने का एक विकल्प है (जैसे ओपी ने किया)

for (i in unique(df$cat)) df$num[df$cat == i] <- seq_len(sum(df$cat == i))

9

यहां एक छोटा सुधार चाल है जो समूहों के अंदर 'वैल' को सॉर्ट करने की अनुमति देता है:

# 1. Data set
set.seed(100)
df <- data.frame(
  cat = c(rep("aaa", 5), rep("ccc", 5), rep("bbb", 5)), 
  val = runif(15))             

# 2. 'dplyr' approach
df %>% 
  arrange(cat, val) %>% 
  group_by(cat) %>% 
  mutate(id = row_number())

क्या आप group_by के बाद सॉर्ट नहीं कर सकते हैं?
zcoleman

6

मैं फ़ंक्शन data.tableका उपयोग करके एक प्रकार जोड़ना चाहता हूं rank()जो ऑर्डर बदलने के लिए अतिरिक्त संभावना प्रदान करता है और इस तरह यह seq_len()समाधान की तुलना में थोड़ा अधिक लचीला बनाता है और RDBMS में row_number फ़ंक्शन के समान सुंदर है।

# Variant with ascending ordering
library(data.table)
dt <- data.table(df)
dt[, .( val
   , num = rank(val))
    , by = list(cat)][order(cat, num),]

    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

# Variant with descending ordering
dt[, .( val
   , num = rank(-val))
    , by = list(cat)][order(cat, num),]

5

एक और dplyrसंभावना हो सकती है:

df %>%
 group_by(cat) %>%
 mutate(num = 1:n())

   cat      val   num
   <fct>  <dbl> <int>
 1 aaa   0.0564     1
 2 aaa   0.258      2
 3 aaa   0.308      3
 4 aaa   0.469      4
 5 aaa   0.552      5
 6 bbb   0.170      1
 7 bbb   0.370      2
 8 bbb   0.484      3
 9 bbb   0.547      4
10 bbb   0.812      5
11 ccc   0.280      1
12 ccc   0.398      2
13 ccc   0.625      3
14 ccc   0.763      4
15 ccc   0.882      5

3
1:n()उपयोग करने के बजाय कुछ मामलों seq_len(n())में सुरक्षित है, इस घटना में कि आपके संचालन के अनुक्रम में आपके पास एक ऐसी स्थिति है जो n()वापस आ सकती है 0, क्योंकि 1:0आपको एक लंबाई दो वेक्टर seq_len(0)देती है जबकि एक लंबाई शून्य वेक्टर देती है, इस प्रकार एक लंबी बेमेल त्रुटि से बचा जाता है mutate()
ब्रायन स्टैम्पर

0

में rowid()समारोह का उपयोग data.table:

> 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$num <- data.table::rowid(df$cat)
> df
   cat        val num
4  aaa 0.05638315   1
2  aaa 0.25767250   2
1  aaa 0.30776611   3
5  aaa 0.46854928   4
3  aaa 0.55232243   5
10 bbb 0.17026205   1
8  bbb 0.37032054   2
6  bbb 0.48377074   3
9  bbb 0.54655860   4
7  bbb 0.81240262   5
13 ccc 0.28035384   1
14 ccc 0.39848790   2
11 ccc 0.62499648   3
15 ccc 0.76255108   4
12 ccc 0.88216552   5

1
आपके उत्तर के लिए धन्यवाद, लेकिन यह पहले से ही @ mnel के उत्तर में अंतिम सुझाव में शामिल किया गया लगता है
eli-k
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.