2015-05-16 2 views
2

Как создать вектор значений из n-го столбца некоторого фрейма данных, где n - значение для каждой строки, определенное в каком-либо векторе? Пример:Возьмите значение из n-го столбца фрейма данных, для n разных для каждой строки

> df <- data.frame(a=c(100, 110, 120, 130, 140), 
        b=c(200, 210, 220, 230, 240), 
        c=c(300, 310, 320, 330, 340)) 
> df 
    a b c 
1 100 200 300 
2 110 210 310 
3 120 220 320 
4 130 230 330 
5 140 240 340 
> cl <- c(1, 3, 3, 2, 1) 
> some.function(df, cl) 

приведет:

[1] 100 310 320 230 140 

ответ

3

Можно индексировать матрицей 2-столбца - первый столбец имеет номер строки, а второй номер столбца.

df[cbind(seq(cl), cl)] 
# [1] 100 310 320 230 140 

Это Векторизованная операция, которая должна быть быстрее, чем цикл по строкам с чем-то вроде sapply и захватывая соответствующее значение из этой строки:

# Slightly larger example, with 1000 rows 
set.seed(144) 
df <- matrix(rnorm(3000), nrow=1000) 
cl <- sample(3, 1000, replace=TRUE) 
all.equal(df[cbind(seq(cl), cl)], sapply(seq(nrow(df)), function(i) df[i, cl[i]])) 
# [1] TRUE 
library(microbenchmark) 
microbenchmark(df[cbind(seq(cl), cl)], sapply(seq(nrow(df)), function(i) df[i, cl[i]])) 
# Unit: microseconds 
#            expr  min  lq  mean median 
#       df[cbind(seq(cl), cl)] 23.828 26.335 34.26012 30.0350 
# sapply(seq(nrow(df)), function(i) df[i, cl[i]]) 855.481 922.449 1178.47502 996.3815 
#   uq  max neval 
# 38.0315 135.894 100 
# 1111.3960 3414.374 100 
+0

Ха, лучше, чем мой собственный 'sapply (Seq (nrow (df)), функция (i) df [i, cl [i]]). Спасибо! – liori

Смежные вопросы