2014-11-17 12 views
5

में एक नई पंक्ति के रूप में परिवहन करें मेरे पास एक डेटा फ्रेम है जो किसी अन्य कमांड का परिणाम है। इस डेटा फ्रेम में लगभग 400 पंक्ति प्रविष्टियों के साथ केवल एक पंक्ति है। मेरी समस्या यह है कि 3 कॉलम डेटा के एक जुड़े सेट हैं। इसलिए मैं प्रत्येक तीसरे कॉलम के बाद पंक्ति को विभाजित करना चाहता हूं और इसे एक नई पंक्ति के रूप में परिवहन करना चाहता हूं। उदाहरण:प्रत्येक 3 कॉलम के बाद एक पंक्ति को विभाजित करें और उन 3 कॉलम को आर

एक परीक्षण डेटा फ्रेम बनाएँ:

df=as.data.frame(matrix(seq(1:12), ncol=12, nrow=1)) 

अब मैं एक डेटा फ्रेम जो इस तरह दिखता है।

V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 
1 2 3 4 5 6 7 8 9 10 11 12 

लेकिन मैं इसे इस तरह की जरूरत है:

V1 V2 V3 
1 2 3 
4 5 6 
7 8 9 
10 11 12 

मैं कैसे यह एहसास कर सकते हैं?

+1

मेरे लिए लगता है कि आपका आदेश है कि समस्या पैदा ठीक करना चाहिए स्रोत पर इस समस्या को ठीक करना चाहिए! क्या आप समझा सकते हैं कि आप कैसे शुरू करने के लिए एक सुपर-विस्तृत डेटा फ्रेम के साथ समाप्त हुए? – A5C1D2H2I1M1N2O1R2T1

उत्तर

4

as.data.frame(matrix(unlist(df, use.names=FALSE),ncol=3, byrow=TRUE)) 
# V1 V2 V3 
#1 1 2 3 
#2 4 5 6 
#3 7 8 9 
#4 10 11 12 

प्रयास करें या आप सीधे पर matrix इस्तेमाल कर सकते हैं df

as.data.frame(matrix(df, ncol=3, byrow=TRUE)) 
+0

सुनिश्चित नहीं है कि तीसरे विकल्प (या पहले) का अतिरिक्त मूल्य क्या था :) –

+0

@ डेविड एरिनबर्ग तीसरा विकल्प स्पष्ट रूप से धीमा होना चाहिए क्योंकि हम 't' ले रहे हैं। मैंने पहला विकल्प पोस्ट किया और फिर एहसास हुआ कि यह 'unlist' का उपयोग किए बिना किया जा सकता है। – akrun

2

भी

as.data.frame(t(`dim<-`(unlist(df), c(3, 4)))) 
# V1 V2 V3 
# 1 1 2 3 
# 2 4 5 6 
# 3 7 8 9 
# 4 10 11 12 
1

यह साबित हुआ है (बस सामान्य ज्ञान के लिए) dim<- उपयोग करने का प्रयास किया जा सका मुझे उम्मीद से तेज (हालांकि stil मैं जितना तेज़ दृष्टिकोण नहीं करता हूं, उतना तेज़ है जितना कि @ अक्रुन ने लिया), इसलिए मैं इसे "सामान्य ज्ञान के लिए" (डेविड की तरह) पोस्ट करने जा रहा हूं।

  1. अपने एकल पंक्ति के गैर-सूचीबद्ध मान: (। साथ ही, "data.table" सभी चीजें) :-)

    एक तीन के साथ data.table कॉलम बनाएँ।

  2. एक समूह चरणीय यह इंगित करने के लिए कि अंतिम पंक्ति में मूल्य को किस पंक्ति को असाइन किया जाना चाहिए।
  3. एक समूह परिवर्तक यह इंगित करने के लिए कि अंतिम आउटपुट में मूल्य को कौन सा कॉलम असाइन किया जाना चाहिए।

एक बार आपके पास यह हो जाने के बाद, आप आउटपुट प्राप्त करने के लिए dcast.data.table का उपयोग कर सकते हैं (साथ ही बोनस कॉलम)।

ऊपर बिंदु संख्या 2 के लिए, हम आसानी से की तरह एक समारोह को परिभाषित कर सकते आसान बनाने समूहों की प्रक्रिया बनाने के लिए निम्नलिखित: इस प्रकार

groupMaker <- function(vecLen, perGroup) { 
    (0:(vecLen-1) %/% perGroup) + 1 
} 

तो हम इसका इस्तेमाल कर सकते हैं:

dcast.data.table(
    data.table(value = unlist(df, use.names = FALSE), 
      row = groupMaker(ncol(df), 3), 
      col = 1:3), 
    row ~ col) 
# row 1 2 3 
# 1: 1 1 2 3 
# 2: 2 4 5 6 
# 3: 3 7 8 9 
# 4: 4 10 11 12 

अब, आप उल्लेख करते हैं कि आप वास्तव में एक सिंगल-पंक्ति ~ 40 के कॉलम data.frame से निपट रहे हैं (मुझे लगता है कि यह 3 9, 999 कॉलम होने के बाद से यह 3 से अच्छी तरह से विभाजित है और मैं प्रजनन नहीं करना चाहता अन्य उत्तर)।

यह ध्यान में रखते हुए, यहां कुछ (बेकार) मानक हैं (बेकार हैं क्योंकि हम वास्तव में यहां मिलीसेकंड्स की बात कर रहे हैं)।

set.seed(1) 
S <- sample(20, 39999, TRUE) 
S <- data.frame(t(S)) 

funAM <- function(indf) { 
    dcast.data.table(
    data.table(value = unlist(indf, use.names = FALSE), 
       row = groupMaker(ncol(indf), 3), 
       col = 1:3), 
    row ~ col) 
} 

funDA <- function(indf) { 
    as.data.frame(t(`dim<-`(unlist(indf), c(3, ncol(indf)/3)))) 
} 

funAK <- function(indf) as.data.frame(matrix(indf, ncol=3, byrow=TRUE)) 

library(microbenchmark) 
microbenchmark(funAM(S), funDA(S), funAK(S)) 
# Unit: milliseconds 
#  expr  min  lq  mean median  uq  max neval 
# funAM(S) 18.487001 18.813297 22.105766 18.999891 19.455812 50.25876 100 
# funDA(S) 37.187177 37.450893 40.393893 37.870683 38.869726 94.20128 100 
# funAK(S) 5.018571 5.149758 5.929944 5.271679 5.536449 26.93281 100 

जहां इस पराक्रम उपयोगी मामलों में जहां वांछित स्तंभों की संख्या और इनपुट स्तंभों की अपनी संख्या अच्छी तरह से एक दूसरे को विभाजित नहीं कर रहे हैं में होगा होना।

उदाहरण के लिए, निम्न नमूना डेटा का प्रयास करें:

set.seed(1) 
S2 <- sample(20, 40000, TRUE) 
S2 <- data.frame(t(S)) 

इस नमूना डेटा के साथ:

  • funAM आप एक warning देना होगा लेकिन सही ढंग से आप अंतिम पंक्ति के अंतिम दो कॉलम देना होगा NA के रूप में।
  • funAK आपको warning देगा लेकिन आखिरी पंक्ति में गलत तरीके से रीसायकल मान देगा (संभवतः)।
  • funDA आपको केवल error देगा।

मैं अब भी लगता है कि तुम सिर्फ हालांकि :-)

संबंधित मुद्दे