2013-03-12 95 views
2

我试图将回归函数应用于因子(主题)的每个单独的级别。这个想法是,对于每个主题,我可以根据他们的实际阅读时间(RT)和相应打印字符串(WordLen)的长度来获得预测阅读时间。一位同事帮助我解决了一些基于(Subject)中另一个函数(Region)的每个级别应用函数的代码。但是,无论是原始代码还是我的尝试修改(在单个因素间使用跨功能的功能)都可以使用。应用回归,同时循环R中的因子水平

下面是一些样本数据的尝试:

test0<-structure(list(Subject = c(101L, 101L, 101L, 101L, 101L, 101L, 
101L, 101L, 101L, 101L, 102L, 102L, 102L, 102L, 102L, 102L, 102L, 
102L, 102L, 102L, 103L, 103L, 103L, 103L, 103L, 103L, 103L, 103L, 
103L, 103L), Region = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 
2L, 2L, 2L, 2L), RT = c(294L, 241L, 346L, 339L, 332L, NA, 399L, 
377L, 400L, 439L, 905L, 819L, 600L, 520L, 811L, 1021L, 508L, 
550L, 1048L, 1246L, 470L, NA, 385L, 347L, 592L, 507L, 472L, 396L, 
761L, 430L), WordLen = c(3L, 3L, 3L, 3L, 3L, 3L, 5L, 7L, 3L, 
9L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 5L, 7L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 5L, 7L, 3L)), .Names = c("Subject", "Region", "RT", "WordLen" 
), class = "data.frame", row.names = c(NA, -30L)) 

不幸的是,这个数据正在恢复,我不跟我的完整数据集得到了一个问题:

"Error in lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) : 
    0 (non-NA) cases" 

也许这是因为样本数据太小?

无论如何,我希望有人看到这个问题的代码,尽管我提供工作数据的能力......

这是原来的代码(不工作):

for(i in 1:length(levels(test0$Subject))) 
    for(j in 1:length(levels(test0$Region))) 
    {tmp=predict(lm(RT~WordLen,test0[test0$Subject==levels(test0$Subject)[i] & test0$Region==levels(test0$Region)[j],],na.action="na.exclude")) 
    test0[names(tmp),"rt.predicted"]=tmp 
    } 

,这是修改后的代码(这并不奇怪,也不起作用):

for(i in 1:length(levels(test0$Subject))) 
    {tmp=predict(lm(RT~WordLen,test0[test0$Subject==levels(test0$Subject)[i],],na.action="na.exclude")) 
    test0[names(tmp),"rt.predicted"]=tmp 
    } 

我将非常感谢任何建议。

+2

也看到'? 'nlme'包中的lmList'。 – 2013-03-12 12:44:18

回答

3

您可以使用库plyr中的函数ddply()获得结果。 这将根据Subject拆分数据帧,计算回归模型的预测,然后作为新列添加到数据帧。

ddply(test0,.(Subject),transform, 
    pred=predict(lm(RT~WordLen,na.action="na.exclude"))) 

    Subject Region RT WordLen  pred 
1  101  1 294  3 327.9778 
...... 
4  101  1 339  3 327.9778 
5  101  1 332  3 327.9778 
6  101  2 NA  3  NA 
7  101  2 399  5 363.8444 
....... 
13  102  1 600  3 785.4146 

要通过Subject和拆分数据Region你应该把两个变量中.()

ddply(test0,.(Subject,Region),transform, 
    pred=predict(lm(RT~WordLen,na.action="na.exclude"))) 
+0

这很好用,谢谢。我如何修改这个也是按区域分割的(对每个主题的每个区域进行回归)? – 2013-03-12 12:31:49

+0

@DT更新了我的答案。 – 2013-03-12 12:35:46

+0

非常好。我仍然好奇原始循环方法为什么不起作用。我意识到循环不应该成为我与R的第一线攻击,但它是很好的知道。 – 2013-03-12 12:41:34

2

在测试数据的唯一问题是,SubjectRegion不是因素。

test0$Subject <- factor(test0$Subject) 
test0$Region <- factor(test0$Region) 

for(i in 1:length(levels(test0$Subject))) 
    for(j in 1:length(levels(test0$Region))) 
    {tmp=predict(lm(RT~WordLen,test0[test0$Subject==levels(test0$Subject)[i] & test0$Region==levels(test0$Region)[j],],na.action="na.exclude")) 
    test0[names(tmp),"rt.predicted"]=tmp 
    } 
# 26  27  28  29  30 
# 442.25 442.25 560.50 678.75 442.25 

原因你让你的错误(0 non-NA cases)是当你子集,你在做它是不是因素的变量水平。在你原始数据集,尝试:

test0[test0$Subject==levels(test0$Subject)[1],] 

你得到:

# [1] Subject Region RT  WordLen 
# <0 rows> (or 0-length row.names) 

这是什么lm()试图用

+0

谢谢你收到这个错误。在我的原始数据中,它们是因素,但是在裁减数据时我错过了这一点。 – 2013-03-12 12:30:23

0

工作,我会认为这是由以下事实引起的两个分类变量的组合不存在数据。你可以做的是首先提取子集,检查它是否不等于NULL,并且只有在有数据时才执行lm。

2

虽然你的问题好像是问错误的解释,这人已经回答(数据不被因素在所有),这里是一个办法做到这一点只用base

test0$rt.predicted <- unlist(by(test0[, c("RT", "WordLen")], list(test0$Subject, test0$Region), FUN = function(x) predict(lm(RT ~ 
    WordLen, x, na.action = "na.exclude")))) 

test0 
## Subject Region RT WordLen rt.predicted 
## 1  101  1 294  3  310.4000 
## 2  101  1 241  3  310.4000 
## 3  101  1 346  3  310.4000 
## 4  101  1 339  3  310.4000 
## 5  101  1 332  3  310.4000 
## 6  101  2 NA  3  731.0000 
## 7  101  2 399  5  731.0000 
## 8  101  2 377  7  731.0000 
## 9  101  2 400  3  731.0000 
## 10  101  2 439  9  731.0000 
## 11  102  1 905  3  448.5000 
## 12  102  1 819  3   NA 
## 13  102  1 600  3  448.5000 
## 14  102  1 520  3  448.5000 
## 15  102  1 811  3  448.5000 
## 16  102  2 1021  3   NA 
## 17  102  2 508  3  399.0000 
## 18  102  2 550  5  408.5000 
## 19  102  2 1048  7  389.5000 
## 20  102  2 1246  3  418.0000 
## 21  103  1 470  3  870.4375 
## 22  103  1 NA  3  870.4375 
## 23  103  1 385  3  877.3750 
## 24  103  1 347  3  884.3125 
## 25  103  1 592  3  870.4375 
## 26  103  2 507  3  442.2500 
## 27  103  2 472  3  442.2500 
## 28  103  2 396  5  560.5000 
## 29  103  2 761  7  678.7500 
## 30  103  2 430  3  442.2500 
+0

谢谢你的替代 - 。因素水平问题只是次要的。真正的问题是我的代码不适用于真正的数据集(正确编码的因子水平)。或者我错了,你是说我的原代码应该已经工作? – 2013-03-12 21:14:34