【发布时间】:2014-05-21 09:23:37
【问题描述】:
我设法编写了一段相当笨重的代码,它在很大程度上可以满足我的需求,但问题是它速度慢而且我的数据库太大,这意味着基本上不行。我制作了一个可重现的数据集,我会尽量解释我需要做什么:
Y <-structure(list(X1 = structure(c(2L, 2L, 2L, 3L, 3L, 6L, 6L, 4L, 4L, 4L, 4L, 4L,4L, 4L, 5L, 5L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("23", "2636","15B","2637", "2638", "2639"), class = "factor"), X2 = structure(c(16L, 16L, 18L, 8L, 10L, 16L, 17L, 8L, 11L, 13L, 15L, 15L, 17L, 17L, 8L, 10L, 1L, 1L, 2L, 3L, 3L, 4L, 4L, 5L, 6L, 6L, 7L, 7L, 7L, 7L, 9L, 9L, 10L, 12L, 13L, 13L, 14L, 14L, 14L, 14L), .Label = c("1980", "1981", "1982", "1983", "1984", "1986", "1987", "1988", "1989", "1990", "1991", "1992", "1993", "1994", "1995", "1996", "1997", "1998"), class = "factor"), X3 = structure(c(4L, 11L, 4L, 3L, 14L, 5L, 5L, 12L, 12L, 8L, 8L, 12L, 5L, 8L, 4L, 4L, 3L, 4L, 3L, 3L, 13L, 8L, 10L, 15L, 3L, 14L, 3L, 4L, 8L, 14L, 1L, 3L, 3L, 14L, 3L, 6L, 1L, 2L, 7L, 9L), .Label = c("ABT", "AZN", "BAX", "BAY", "BMS", "GET", "GSK", "JNJ", "LIL", "MER", "NOV", "PFI", "S.A", "SAG", "SHI"), class = "factor"), X4 = structure(c(3L, 3L, 3L, 2L, 2L, 3L, 3L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("1980", "1988", "1996"), class = "factor"), X5 = structure(c(5L, 5L, 5L, 2L, 2L, 4L, 4L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("1981", "1990", "1991", "1997", "1998"), class = "factor")), .Names = c("X1", "X2", "X3", "X4", "X5"), row.names = c(NA, 40L), class = "data.frame")
Y<-data.frame(Y)
colnames(Y)<-c("s","y","f","pb","pbs")
Y[,"pbc"]<-NA
Y<-Y[order(Y$s, decreasing =F),]
Y$s<-as.character(Y$s)
Y$y<-as.numeric(as.character(Y$y))
Y$pb<-as.numeric(as.character(Y$pb))
Y$pbs<-as.numeric(as.character(Y$pbs))
ff
在此数据框中 s = 符号,y = 年份,f = 公司,pb = 第一个符号的年份,如果符号出现在第一个符号的 3 年内,pbs = 第二个符号的年份,pbc 指的是新变量“符号”确认”。 pb 和 pbs 已在行业级别进行编码,现在我想找出具有第一个符号 (pb) 的公司是否也具有第二个符号 (pbs)。如果是这种情况,pbc 的值应该取 pbs 的值。 ff 是所有公司的列表。
这是我目前的代码:
for (j in 1:length(ff)){
a<-as.vector(table(Y[Y$f ==ff[j],][,"s"]))
for (k in 1:(length(levels(as.factor(Y[Y$f ==ff[j],][,"s"]))))) {
for (i in 1:(nrow(Y[Y$f ==ff[j],])-1)) {
Y[Y$f ==ff[j],][,"pbc"][i] <-
if ((a[k] > 1) &&
(Y[Y$f ==ff[j],][,"y"][i] == Y[Y$f ==ff[j],][,"pb"][i])
&&
(Y[Y$f ==ff[j],][,"y"][i+1] == Y[Y$f ==ff[j],][,"pbs"][i+1]))
{Y[Y$f ==ff[j],][,"pbs"][i]}
else {0}
}}}
它看起来很复杂,但它的作用如下:
- 我将一个特定的公司 j 隔离到一个 subdata.frame
Y[Y$f ==ff[j],] - 我检查“s”有多少个不同的值(通过表格)
- 如果至少有两行重复“s”值
(a[k] > 1)检查是否满足其他两个条件。如果是,添加“pbs”的值
现在这个结果有效,但包含两个问题。
- 首先,总是有一些值保留
NA。我不认为它们会造成任何问题,但立即摆脱这些 NA 会很棒(就我而言) - 效率不高,我认为我的简单计算机无法处理整个数据集(具有 > 2500 个标志、> 30 年、> 35 家公司)
当前代码的预期结果(注意理想情况下不应出现 NA 值)
pbc = c(0,0,1981,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,NA,NA,0,NA,,0,0,0,1998,0,0,1991,0,0,0,NA,0,NA,1(90,NA,1997,NA)
为了进一步阐明我建议的代码应该如何工作,我运行了其中的一部分,希望能更清楚地一次性显示我想要做什么。
bayY<-Y[Y$f == "BAY",]
for (i in 1:nrow(bayY)-1){
bayY$pbc[i+1] <-
if ((bayY$s[i] == bayY$s[i+1]) && (bayY$y[i] == bayY$pb[i]) && (bayY$y[i+1] == bayY$pbs[i+1])) {bayY$pbs[i+1]}
else {0}
}
因此,我在隔离该公司后测试该公司的条件。结果给了我所有正确的值。我可以为每家公司执行此操作,然后将它们全部合并到一个新的 df 中,但必须有一种方法可以更有效地执行此操作...
【问题讨论】:
-
你的例子给了我以下错误:
Error in Ops.factor(Y[Y$f == ff[j], ][, "y"][i], Y[Y$f == ff[j], ][, "pb"][i]) : level sets of factors are different -
一般代码建议:每次写
Y[Y$f ==ff[j],][,"s"]这样的索引表达式,就写Y[Y$f ==ff[j],"s"]即可。不需要两组括号。 -
你的例子也有问题(上面的错误),因为试图比较不同水平的因素。您需要将所有内容转换为字符或数字,以便在整个代码中进行
==比较。 -
谢谢Thomas,我忘了把那些“as.character()”命令和昨天一样。我在编辑中添加了它们。感谢您的格式建议,看起来会更好。
标签: r loops if-statement for-loop