-1

这是一个示例数据框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

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

4

3 回答 3

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为与哈德利在评论中讨论的那样。

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
于 2013-09-20T13:09:30.137 回答
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的元素个数不一样

于 2013-09-20T13:19:35.837 回答
0

tail(x,n)withnegativen返回 x 的所有元素,不包括第一个元素n

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

编辑(米歇尔):由于您希望它返回一个包含由s您定义的行的子集,因此您需要增加b一。

mapply(function(a,b) tail(a, -b+1), df, s)
于 2013-09-20T12:56:53.807 回答