डेटाफ्रेम को कैसे विभाजित किया जाए, इसके लिए कई उत्तर हैं, उदाहरण के लिए डेटा फ़्रेम कैसे विभाजित करें?

हालाँकि, मैं एक डेटाफ़्रेम को विभाजित करना चाहूंगा ताकि छोटे डेटाफ़्रेम में पिछली डेटाफ़्रेम की अंतिम पंक्ति और निम्नलिखित डेटाफ़्रेम की पहली पंक्ति हो।

यहाँ एक उदाहरण है

n <- 1:9
group <- rep(c("a","b","c"), each = 3)
data.frame(n = n, group)

  n  group
1 1     a
2 2     a
3 3     a
4 4     b
5 5     b
6 6     b
7 7     c
8 8     c
9 9     c

मैं आउटपुट को पसंद करना चाहूंगा:

 d1 <- data.frame(n = 1:4, group = c(rep("a",3),"b"))
 d2 <- data.frame(n = 3:7, group = c("a",rep("b",3),"c"))
 d3 <- data.frame(n = 6:9, group = c("b",rep("c",3)))
 d <- list(d1, d2, d3)
 d

[[1]]
  n group
1 1     a
2 2     a
3 3     a
4 4     b

[[2]]
  n group
1 3     a
2 4     b
3 5     b
4 6     b
5 7     c

[[3]]
  n group
1 6     b
2 7     c
3 8     c
4 9     c

इस कार्य को पूरा करने का एक कुशल तरीका क्या है?

4
Tedward 18 नवम्बर 2015, 23:21

5 जवाब

सबसे बढ़िया उत्तर

मान लें कि DF मूल डेटा है। फ़्रेम, वह कॉलम n और group है। DF पंक्तियों की संख्या n होने दें। अब एक फ़ंक्शन extract को परिभाषित करें, जिसने अनुक्रमित ix का एक क्रम दिया है, इसे पहले और बाद में पहले वाले को शामिल करने के लिए बढ़ाता है और फिर DF की उन पंक्तियों को वापस करता है। अब हमने extract को परिभाषित किया है, वेक्टर 1, ..., n को समूह द्वारा विभाजित करें और विभाजन के प्रत्येक घटक पर extract लागू करें।

n <- nrow(DF)
extract <- function(ix) DF[seq(max(1, min(ix) - 1), min(n, max(ix) + 1)), ]
lapply(split(seq_len(n), DF$group), extract)

$a
  n group
1 1     a
2 2     a
3 3     a
4 4     b

$b
  n group
3 3     a
4 4     b
5 5     b
6 6     b
7 7     c

$c
  n group
6 6     b
7 7     c
8 8     c
9 9     c
5
G. Grothendieck 19 नवम्बर 2015, 02:10

या क्यों नहीं की कोशिश करें good'ol by, जो "[a] ppl [ies] कारक द्वारा एक डेटा फ़्रेम स्प्लिट के लिए एक फंक्शन [INDICES]"।

by(data = df, INDICES = df$group, function(x){
   id <- c(min(x$n) - 1, x$n, max(x$n) + 1)
   na.omit(df[id, ])
   })


# df$group: a
#   n group
# 1 1     a
# 2 2     a
# 3 3     a
# 4 4     b
# -------------------------------------------------------------------------------- 
#   df$group: b
# n group
# 3 3     a
# 4 4     b
# 5 5     b
# 6 6     b
# 7 7     c
# -------------------------------------------------------------------------------- 
#   df$group: c
#   n group
# 6 6     b
# 7 7     c
# 8 8     c
# 9 9     c

यद्यपि {{एक्स 1}} विधि {{एक्स 1}} एक 'फैंसी' आउटपुट बनाता है, (डिफ़ॉल्ट) परिणाम एक list है, जिसमें समूह चर के स्तरों द्वारा नामित तत्व हैं (बस {{X3) प्रयास करें। }} और names परिणामी वस्तु पर)।

4
Henrik 19 नवम्बर 2015, 09:30

मैं @cdetermans जवाब के तहत टिप्पणी करने जा रहा था, लेकिन अब बहुत देर हो चुकी है। समूह सूचकांकों को खोजने के लिए आप data.table::shift (या dyplr::lag) का उपयोग करके उनके दृष्टिकोण को सामान्य कर सकते हैं और फिर श्रेणियों पर एक साधारण lapply चला सकते हैं, कुछ इस तरह

library(data.table) # v1.9.6+ 
indx <- setDT(df)[, which(group != shift(group, fill = TRUE))]
lapply(Map(`:`, c(1L, indx - 1L), c(indx, nrow(df))), function(x) df[x,])
# [[1]]
#    n group
# 1: 1     a
# 2: 2     a
# 3: 3     a
# 4: 4     b
# 
# [[2]]
#    n group
# 1: 3     a
# 2: 4     b
# 3: 5     b
# 4: 6     b
# 5: 7     c
# 
# [[3]]
#    n group
# 1: 6     b
# 2: 7     c
# 3: 8     c
# 4: 9     c
3
David Arenburg 18 नवम्बर 2015, 20:52

डेटा.फ्रेम के साथ भी किया जा सकता है, लेकिन क्या कभी data.table का उपयोग नहीं करने का कोई कारण है? इसके अलावा यह समानता के साथ निष्पादित होने का विकल्प है।

library(data.table)
n <- 1:9
group <- rep(c("a","b","c"), each = 3)
df <- data.table(n = n, group)
df[, `:=` (group = factor(df$group))]
df[, `:=` (group_i = seq_len(.N), group_N = .N), by = "group"]

library(doParallel)
groups <- unique(df$group)
foreach(i = seq(groups)) %do% {
  df[group == groups[i] | (as.integer(group) == i + 1 & group_i == 1) | (as.integer(group) == i - 1 & group_i == group_N), c("n", "group"), with = FALSE]  
}
[[1]]
   n group
1: 1     a
2: 2     a
3: 3     a
4: 4     b
[[2]]
   n group
1: 3     a
2: 4     b
3: 5     b
4: 6     b
5: 7     c
[[3]]
   n group
1: 6     b
2: 7     c
3: 8     c
4: 9     c
1
mlegge 18 नवम्बर 2015, 21:51

यहाँ एक और शानदार तरीका है:

library(dplyr)

data = 
  data_frame(n = n, group) %>%
  group_by(group)

firsts = 
  data %>%
  slice(1) %>%
  ungroup %>%
  mutate(new_group = lag(group)) %>%
  slice(-1)

lasts = 
  data %>%
  slice(n()) %>%
  ungroup %>%
  mutate(new_group = lead(group)) %>%
  slice(-n())

bind_rows(firsts, data, lasts) %>%
  mutate(final_group = 
           ifelse(is.na(new_group),
                  group,
                  new_group) ) %>%
  arrange(final_group, n) %>%
  group_by(final_group)
0
bramtayl 18 नवम्बर 2015, 22:42