2017-10-04 65 views
1

我有一個表格,格式如下。分割表格並寫入多個.txt文件

Category Value 
Name_01 10 
Name_01 12 
Name_01 11 
Name_02 12 
Name_02 1 
Name_03 13 
Name_04 11 
Name_05 12 
Name_06 21 
Name_07 3 
Name_08 1 
Name_09 23 
Name_10 1 
Name_11 123 
Name_12 12 
Name_13 1 
Name_14 1 
Name_15 12 
Name_16 1 
Name_17 2 
Name_18 33 
Name_19 21 
Name_20 123 
Name_21 32 
Name_22 23 
Name_23 21 

我想將表格寫入.txt文件,但每個.txt文件最多隻能處理20個獨特的類別。因此,該表需要根據類別的總數分成多個.txt文件。有誰知道我可以如何使用base R來做到這一點?另一個複雜因素是所有的.txt文件必須具有從1-20編號的類別。在下面的示例中,我將包含一個包含names_01-20的.txt文件,以及包含names_21-23但重命名爲names_01-03的第二個.txt文件。

+0

道歉,我還沒有找到解決辦法。有沒有人有任何想法? –

回答

1

嘗試這種情況:

# split 
myList <- 
    lapply(split(df1, as.numeric(df1$Category) %/% 21 + 1), 
     function(i){ 
      x <- i 
      x$Category <- droplevels(x$Category) 
      x$Category <- as.factor(as.numeric(x$Category)) 
      x 
     }) 

# write to csv 
lapply(names(myList), function(i) write.csv(myList[[ i ]], 
              file = paste0(i, ".csv"), 
              row.names = FALSE)) 

這將輸出2個文件:1.csv2.csv

+0

謝謝,道歉,但我不知道如何使用它來寫我的文本文件? –

+0

非常感謝。我嘗試了這一點,並得到了以下錯誤'在split.default(seq_len(nrow(x)),f,drop):強制引入NAs(525次)' –

+0

謝謝,我已經完成,我沒有包括所有525行雖然。 –

1

另一種解決方案:

maxCategory <- 20 
N <- ceiling(1:nrow(data)/maxCategory) 

for(i in unique(N)) { 
    d <- data[N == i, ] 
    # Get category with 0 
    foo <- 1:nrow(d) 
    foo <- ifelse(foo < 10, paste0("0", foo), foo) 
    d$Category <- paste0("Name_", foo) 
    # Write text file 
    write.table(d, paste0("split_", i, ".txt"), 
       row.names = FALSE, quote = FALSE) 
} 

輸出文件是:split_1.txtsplit_2.txtsplit_2.txt看起來像這樣:

Category Value 
Name_01 32 
Name_02 23 
Name_03 21 
+1

謝謝,對不起,我不確定這是否有效,因爲我可能有多個具有相同類別值的行。 –

+0

@ Ash_23S您必須編輯您的問題並提供示例數據,然後我可以將我的代碼調整爲:-) – PoGibas

+0

謝謝,我現在已經這樣做了。不管每個.txt文件中有多少行,只要最多有20個獨特的類別。 –

0

這是一個完美的解決方案。

library('magrittr') 
library('tidyverse') 

df <- tribble(
    ~Category, ~Value, 
    'Name_01', 10, 
    'Name_02', 12, 
    'Name_03', 13, 
    'Name_04', 11, 
    'Name_05', 12, 
    'Name_06', 21, 
    'Name_07', 3, 
    'Name_08', 1, 
    'Name_09', 23, 
    'Name_10', 1, 
    'Name_11', 123, 
    'Name_12', 12, 
    'Name_13', 1, 
    'Name_14', 1, 
    'Name_15', 12, 
    'Name_16', 1, 
    'Name_17', 2, 
    'Name_18', 33, 
    'Name_19', 21, 
    'Name_20', 123, 
    'Name_21', 32, 
    'Name_22', 23, 
    'Name_23', 21 
) 

首先,我們使用parse_number來提取類別ID。我們使用dense_rank(Category)來獲得不同的類別數量。我們用這個來增加每20個不同類別的group_id。我們還根據該組的最小/最大值category_id創建一個file_name列。

df2 <- df %>% 
    mutate(
    category_id = parse_number(Category), 
    group_id = cumsum(dense_rank(Category) %% 20 == 1)) %>% 
    group_by(group_id) %>% 
    mutate(file_name = stringr::str_c('names_', min(category_id), '-', max(category_id), '.txt')) 

print(df2, n=100) 
# # A tibble: 23 x 6 
# # Groups: group_id [2] 
# Category Value  g category_id group_id  file_name 
#  <chr> <dbl> <dbl>  <dbl> <int>   <chr> 
# 1 Name_01 10  1   1  1 names_1-20.txt 
# 2 Name_02 12  1   2  1 names_1-20.txt 
# 3 Name_03 13  1   3  1 names_1-20.txt 
# 4 Name_04 11  1   4  1 names_1-20.txt 
# 5 Name_05 12  1   5  1 names_1-20.txt 
# 6 Name_06 21  1   6  1 names_1-20.txt 
# 7 Name_07  3  2   7  1 names_1-20.txt 
# 8 Name_08  1  2   8  1 names_1-20.txt 
# 9 Name_09 23  2   9  1 names_1-20.txt 
# 10 Name_10  1  2   10  1 names_1-20.txt 
# 11 Name_11 123  2   11  1 names_1-20.txt 
# 12 Name_12 12  2   12  1 names_1-20.txt 
# 13 Name_13  1  2   13  1 names_1-20.txt 
# 14 Name_14  1  3   14  1 names_1-20.txt 
# 15 Name_15 12  3   15  1 names_1-20.txt 
# 16 Name_16  1  3   16  1 names_1-20.txt 
# 17 Name_17  2  3   17  1 names_1-20.txt 
# 18 Name_18 33  3   18  1 names_1-20.txt 
# 19 Name_19 21  3   19  1 names_1-20.txt 
# 20 Name_20 123  3   20  1 names_1-20.txt 
# 21 Name_21 32  3   21  2 names_21-23.txt 
# 22 Name_22 23  3   22  2 names_21-23.txt 
# 23 Name_23 21  3   23  2 names_21-23.txt 

現在,我們可以將nest的原始列轉換爲列表列。

df2 <- df2 %>% 
    group_by(group_id, file_name) %>% 
    nest(Category, Value) 
print(df2, n=100) 
# # A tibble: 2 x 3 
# group_id  file_name    data 
#  <int>   <chr>   <list> 
# 1  1 names_1-20.txt <tibble [20 x 2]> 
# 2  2 names_21-23.txt <tibble [3 x 2]> 

然後,我們通過walk使用write_delim每個data + file_name對和輸出每個文件。

df2 %$% 
    walk2(
    .$data, 
    .$file_name, 
    write_delim) 

我們可以將上述所有步驟組合到一個管道中。

df %>% 
    mutate(
    category_id = parse_number(Category), 
    group_id = cumsum(dense_rank(Category) %% 20 == 1)) %>% 
    group_by(group_id) %>% 
    mutate(file_name = stringr::str_c('names_', min(category_id), '-', max(category_id), '.txt')) %>% 
    group_by(group_id, file_name) %>% 
    nest(Category, Value) %$% 
    walk2(
    .$data, 
    .$file_name, 
    write_delim) 
+0

非常感謝您的幫助,但我確實需要Base R解決方案,因爲我無法在軟件中使用其他軟件包。 –