以下是示例数据框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
不知道问题出在哪里。有什么建议吗?
答案 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中的元素数量不同