2017-10-04 58 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解决方案,因为我无法在软件中使用其他软件包。 –