2014-11-08 62 views
1

我对R相对较新,花费了一些时间熟悉基本概念之后,现在正在尝试编写我的第一个函数。我想使用该函数对数据框列表进行一些简单的计算。我的数据是这样的(我有超过100个dataframes,所以它被简化):R:将函数应用于数据框列表时出错

d1 <- data.frame(bp1=c(1,2,3),bp2=c(4,5,6), lp=c(4,5,6)) 
d2 <- data.frame(bp1=c(3,2,1),bp2=c(6,5,4), lp=c(2,1,6)) 
my.list <- list(d1, d2) 

我想要做的是采取10^- 一次柱,并用在第3列中的值乘。然后我想根据第一列汇总结果。我的功能看起来是这样的:

bp_calc <- function(x) { 
bp1 <- x[[i]][1] 
lp <- x[[i]][3] 
10^-lp * lp -> x[[i]]$p_logp 
aggregate(x[[i]]$p_logp ~ bp1, data = x, sum) -> result 
return(result) 
} 

要使用该功能对我的数据,我用:

lapply(my.list,bp_calc) 

然而,这引发错误:错误.subset2(X,I,准确=确切):下标越界。我当然试图谷歌和这个论坛,但我不明白我做错了什么。帮助将不胜感激,谢谢!

+1

和哪里'i'发挥作用。我至少可以通过改变'bp1 < - x [[i]] [1]来运行它; lp < - x [[i]] [3]'到'bp1 < - x [,1]; lp < - x [,3]'并移除其他'[[i]]的 – rawr 2014-11-08 16:59:16

+0

非常感谢@rawr!它工作得很好! – lpoulsen 2014-11-09 12:21:54

回答

1

你可以使用transform来创建新的变量p_logpaggregate

bp_calc <- function(x) { 
    aggregate(p_logp~bp1, transform(x, p_logp=10^-lp*lp), sum) 
} 

lapply(my.list, bp_calc) 
+0

谢谢$ akrun!这似乎是一个更简单的方法(至少更少的代码),但我不愿意使用它,因为我不明白变换正在做什么。我查了一下,描述如下:“transform是一个通用函数,它至少目前只对数据框有用,transform.default在可能的情况下将其第一个参数转换为数据框并调用transform.data。框架“...这并没有真正帮助我,但也许你有更好的解释? – lpoulsen 2014-11-09 12:34:13

+0

@lpoulsen我在数据框'x'中创建一个新变量'p_logp',其中'x'是'my.list'的列表元素。检查转换是做什么的一种方法是分离该参数并单独运行,即。 'lapply(my.list,function(x)transform(x,p_log = 10^-lp * lp))'。在你的例子中,你是从数据框列表中创建一个新的变量。 – akrun 2014-11-09 12:39:10

+0

@lpoulsen'transform'返回一个data.frame,所以他所做的实际上是:'x_transformed < - transform(x,p_logp = 10^-lp * lp);聚合(p_logp〜bp1,x_transformed,sum)' – shadowtalker 2014-11-09 14:29:09

0

subscript out of bounds使用它作为data意味着你试图访问一个不存在的列表元素。例如:

l <- as.list(letters[1:3]) 
l[4] # returns list(NULL) 
l[[4]] # error 

那么为什么会发生这种情况呢?仔细看看你的代码。 lapply(my.list, bp_calc)提取my.list的每个元素并将其传递给bp_calc的第一个参数。在这种情况下,每个列表元素都是一个数据框,并且在此过程的任何地方都不会定义。

因此R在定义bp_calc的环境中搜索名为i的变量。在这种情况下,要么发现i,要么它不会,并返回错误。这里R找到i定义在其他地方,因为否则它会说object 'i' not found。并且无论i是什么,它显然不是1,2,3,bp1bp2lp中的任何一个。

你需要在这里做的是要么定义 i里面的功能,或全局定义它(不推荐,因为这是这样的虫子如何在第一时间出现),或者把它作为一个明确的说法(推荐):

bp_calc <- function(x, i) { 
    # stuff 
} 
lapply(my.list, bp_calc, i = something) 

,什么是[R试图与i办?它试图访问x的元素i,然后访问x[[i]]的元素13。请记住,x一个数据帧,而不是数据帧列表,因为lapply分解my.list之前bp_calc被调用。看起来你认为x[[i]]会访问“当前”列表元素,但实际上x本身是当前列表元素,因此x[[i]]实际上是“当前元素的第i个元素my.list”。因此x[[i]][3]是“当前元素my.list的第i个元素的第三个元素”。

你想要的是这样的:

bp_calc <- function(x) { 
    bp1 <- x[[1]] 
    lp <- x[[3]] 
    10^-lp * lp -> x$p_logp 
    aggregate(x$p_logp ~ bp1, data = x, sum) 
    # by the way, R functions automatically return the last evaluated expression 
} 
+0

谢谢,这是很好的详细解释$ ssdecontrol!纠正我,如果我错了,但这是否意味着我应该定义'我',作为列表中我想使用我的功能的每个数据框?例如。对于my.list中的数据帧1和2:bp_calc < - function(x,i){ #stuff } lapply(my.list,bp_calc,i = 1:2) – lpoulsen 2014-11-09 12:24:55

+0

不,但我现在才意识到什么你正在试着用'我'来做。我稍后会做一个编辑 – shadowtalker 2014-11-09 13:44:14