将“单列函数”应用于整个数据框

时间:2013-09-20 11:50:21

标签: r function

以下是示例数据框df和向量s

x1 <- c(12:4, 5:8, NA, NA)
x2 <- c(15:8, 9:15)
df <- data.frame(x1, x2)
s <- c(9,8)

现在我要在s中给出的行号之前删除每列中的值,这些行号与

一起使用

df1 <- df[s[1]:nrow(df[1]), 1]

单列。但我不能让它适用于整个数据框架。 我尝试了以下(以及其他各种功能):

rec  <- function(x){df[s[x]:nrow(df[x]), x]}
df1 <- lapply(df, rec)

但我总是遇到这样的错误:

Error in `[.data.frame`(df, s[x]:nrow(df[x]), x) : undefined columns selected

不知道问题出在哪里。有什么建议吗?

3 个答案:

答案 0 :(得分:3)

试试mapply。一般来说,我在选择对列表(df中的列)使用列表中每个项目的不同参数调用相同函数时选择它:

> mapply(`[`, df, lapply(s, `:`, nrow(df)))
$x1
[1]  4  5  6  7  8 NA NA

$x2
[1]  8  9 10 11 12 13 14 15

上面对每列应用[运算符(作为原子向量)并将每个项目用作参数

> lapply(s, `:`, nrow(df))
[[1]]
[1]  9 10 11 12 13 14 15

[[2]]
[1]  8  9 10 11 12 13 14 15

所以,第一个是df$x1[9:15],第二个df$x2[8:15]。希望这是你想要的。

编辑:sapply已更改为lapply,正如Hadley在评论中所讨论的那样。

EDIT2:比较下面评论中建议的不同方法的一些时间

set.seed(1)
df1 <- data.frame(x1 = rnorm(10000),
                  x2 = rnorm(10000))


method1 <- function(data, limits)
  mapply(`[`, data, lapply(limits, `:`, nrow(data)))

method2 <- function(data, limits)
  mapply(function(x, i) x[-(1:(i-1))], data, limits)


> identical(method1(df1, s),method2(df1, s))
[1] TRUE
> 
> microbenchmark(method1(df1, s),method2(df1, s))
Unit: microseconds
            expr     min       lq   median       uq      max neval
 method1(df1, s) 239.250 250.1550 258.6525 273.0855  423.658   100
 method2(df1, s) 548.734 568.4585 584.3340 599.4075 1664.164   100

答案 1 :(得分:0)

带有tail(x,n)

n会返回x的所有元素,而不会返回第一个n个元素。

mapply(function(a,b) tail(a, -b), df, s)
lapply(1:2, function(x) tail(df[,x], -s[x]))

EDIT(Michele):由于您希望它返回包含s定义的行的子集,因此您需要将b增加一个。

mapply(function(a,b) tail(a, -b+1), df, s)

答案 2 :(得分:0)

df$new<-as.numeric(rownames(df))
s<-as.list(s)
n<-as.list(names(df)[-3])
k<-Map(function(x,y)df[df$new>=x,y],s,n)
[[1]]
[1]  4  5  6  7  8 NA NA

[[2]]
[1]  8  9 10 11 12 13 14 15

如果你想要数据帧:

data.frame(t(do.call(rbind,kk)))



 X1 X2
1  4  8
2  5  9
3  6 10
4  7 11
5  8 12
6 NA 13
7 NA 14
8  4 15

注意:R在此处进行回收,因为X1和X2中的元素数量不同