我之前发过一个类似的问题,但我的问题现在已经改变了,所以我想再发一次。我有一个包含两列的数据表;数量和价值,如下;
number value
1 test1
1 test2
1 test3
2 test4
2 test5
3 test6
3 test7
3 test8
4 test9
5 test10
6 test11
7 test12
8 test13
9 test14
10 test15
11 test16
12 test17
13 test18
14 test19
15 test20
16 test21
17 test22
18 test23
19 test24
20 test25
21 test26
22 test27
23 test28
我想将数据表导出为多个.txt文件。第一个文本文件应包含整个数据表的子集,其中数字介于1-20之间。第二个文本文件应包含数据的子集,其中数字在21-40之间,第三个数字在41-60之间,依此类推。数据表是动态的,因此导出的.txt文件的数量会有所不同。
此外,在所有.txt文件中,'数字'必须在1-20之间。因此,如果数字为21,则必须将其重命名为1,如果数字为22,则必须将其重命名为2,等等。
有人能帮忙吗?在上面的示例中,应该有2个.txt文件,第一个包含25行,第二个包含3行,第二个包含数字21,22,23的.txt文件重命名为1,2,3。
答案 0 :(得分:2)
首先,我会使用split()
将您的数据框拆分为20行的块。此功能将根据某些标准拆分数据框。在你的情况下,这个标准可能是这样的:“行数除以20的结果是什么(四舍五入到上/下整数)?”。根据此规则,输入数据将被拆分。
nrows <- 1:nrow(df)
df <- split(df, floor(nrows/20))
修改:如果您想根据df$number
中的值进行拆分,则应使用df <- split(df, floor((df$number-1)/20))
其次,对于所有高于20的数字,你必须以某种方式转换20的倍数。我会使用modulo %% 20
,但也会将20变换为零。
ready_for_export <- lapply(df, function(x){
x$number <- (x$number - floor((x$number-1)/20)*20)
return(x)})
最后,将列表ready_for_export
中的元素保存在单独的txt文档中。我会使用for
- 循环:
for(i in seq_along(ready_for_export)){
write.table(ready_for_export[[i]], paste0("test", i, ".txt"))
}
可能有一些包,这会使它看起来更好,表现更快,但是,我喜欢尽可能地坚持基础R
。
答案 1 :(得分:1)
tidyverse
允许你编写一个更整洁的解决方案;)
假设您的数据位于变量df
:
library(tidyverse)
df %>%
mutate(set = plyr::round_any(number - 1, 20, floor) %>% as.factor %>% as.numeric) %>%
group_by(set) %>%
mutate(set_num = number %>% as.factor %>% as.numeric) %>%
ungroup ->
df_prep
df_prep$set %>%
unique %>%
walk(~ write_tsv(df_prep %>%
filter(set == .x) %>%
select(number = set_num,
value),
paste0("file-", .x, ".tsv")))
as.factor %>% as.numeric
法案为列的不同值分配新的唯一数字ID。正确的赋值->
有点不寻常,但使magrittr
管道流畅。