双循环使用R保存多个文件

时间:2015-05-25 02:24:36

标签: r for-loop dataframe

我正在尝试执行“for循环”以根据列“group”生成文件。我想为每个组创建一个文件。我的数据要大得多,但样本会是:

id = c(1,2,3,4,5,6,7,8,9,10)
group = c(3,1,3,2,1,3,1,2,4,4)
weight = c(10,11,12,13,14,15,16,17,18,19)
index1 = c(50,50,50,50,50,50,50,50,50,50)
index2 = c(50,50,50,50,50,50,50,50,50,50)
data = data.frame(id,group,weight,index1,index2)
for (i in unique(data$group)){
for (j in 1:nrow(data)){
data$weight[j] = ifelse(data$group[j] == data$group[i], 0,data$weight[j])
data$index1[j] = ifelse(data$group[j] == data$group[i], 0,50)
data$index2[j] = ifelse(data$group[j] == data$group[i], 5,50)
}
write.table(data,paste("/home/paulaf/test/",data$group[i],".txt",sep=""),
               quote=F,row.names=F,col.names=T)}

它似乎工作,但它不会写所有文件。任何帮助将非常感谢。提前谢谢。

3 个答案:

答案 0 :(得分:1)

unique(data$group)是一个长度为4的向量。data$group的长度为10.您要将文件名设置为data$group的前4个值,而不是{的唯一值{1}}。

尝试使用生成文件名的data$group内的data$group[i]替换i,例如

paste

答案 1 :(得分:1)

你的问题非常简单。在write.table函数中,您使用data$group[i]粘贴名称,但外部循环不会循环遍历唯一组的索引,而是遍历组名称本身。您的i3 1 2 4,因此为每个data$group[i]调用3, 3, 1, 2将导致write.table(data,paste("/home/paulaf/test/",i,".txt",sep=""), quote=F,row.names=F,col.names=T)} ,这意味着所有文件名都是错误的(一个文件被替换,您结束这个样本只有3个)。解决方案是:

paste0

使用write.table(data,paste0("/home/paulaf/test/",i,".txt"), quote=F,row.names=F,col.names=T)} 稍微有效(并且更容易阅读,imho),所以:

Firefox 38.0.0 (Windows 8.1) companyService should return a promise for getCompany function FAILED
        minErr/<@C:/Users/user1m/Documents/mycompany/WebApiRole/bower_components/angular/angular.js:63:12
        loadModules/<@C:/Users/user1m/Documents/mycompany/WebApiRole/bower_components/angular/angular.js:4138:15
        forEach@C:/Users/user1m/Documents/mycompany/WebApiRole/bower_components/angular/angular.js:323:11
        loadModules@C:/Users/user1m/Documents/mycompany/WebApiRole/bower_components/angular/angular.js:4099:5
        createInjector@C:/Users/user1m/Documents/mycompany/WebApiRole/bower_components/angular/angular.js:4025:11
        workFn@C:/Users/user1m/Documents/mycompany/WebApiRole/node_modules/angular-mocks/angular-mocks.js:2409:44
        TypeError: companyService is undefined in C:/Users/user1m/Documents/mycompany/WebApiRole/test/company/Compa
nyServiceSpec.js (line 15)
        @C:/Users/user1m/Documents/mycompany/WebApiRole/test/company/CompanyServiceSpec.js:15:16
Firefox 38.0.0 (Windows 8.1): Executed 1 of 1 (1 FAILED) ERROR (0.031 secs / 0.014 secs)    

答案 2 :(得分:1)

保拉,

该代码实际上是在写四个文件。但是你要覆盖其中一个文件,所以你只能以三个文件结束。

当您使用paste命名文件时,您使用data$group[i]生成名称。如果您使用cat()或类似内容查看这些名称,则会发现您有两个3.txt个文件。

/home/paulaf/test/3.txt 
/home/paulaf/test/3.txt 
/home/paulaf/test/1.txt 
/home/paulaf/test/2.txt 

那么,这就是为什么你没有得到所有文件的原因。你的第一个3.txt被覆盖了。

仔细查看data对象,可以看出为什么会发生这种情况。 您的循环中的i将具有值3,1,2和4.通过将1-4插入data$group[i],您实际上会取出1-的值data$group中的第4行。请注意,第一行和第三行都是第3组。

   id group weight index1 index2
1   1     3      0     50     50
2   2     1      0     50     50
3   3     3      0     50     50
4   4     2      0      0      5
5   5     1      0     50     50
6   6     3      0     50     50
7   7     1      0     50     50
8   8     2      0      0      5
9   9     4     18     50     50
10 10     4     19     50     50

也许用这个替换你的write.table()

write.table(data,paste("/home/paulaf/test/",i,".txt",sep=""),
               quote=F,row.names=F,col.names=T)

还有一个注意事项可以帮助您避免将来的头痛:将一些变量打印到控制台通常很有帮助。这只是一种了解发生了什么的方法。

另外,祝你好运,继续与R合作,你做得很棒!