2013-10-08 4 views
3

Я новичок в R и получаю краткий обзор времени, связанного с синтаксисом. Скажем, у меня есть следующие данные кадра данных:Создайте вектор, удовлетворяющий двум факторам в кадре данных

value label second 
1  a  q 
2  a  q 
3  a  ASDF 
4  b  q 
6  b  QWERTY 
6  b  QWERTY 
7  c  q 
8  c  q 
9  c  q 
10  d  q 

Теперь я хочу, чтобы получить вектор df$second, которые соответствуют максимумам df$value для заданного значения df$label. Так, например, учитывая df$label = 'a', я хочу вернуть 'ASDF'. Для df$label = 'b', я хочу вернуть 'QWERTY', 'QWERTY'.

Вот что я хочу:

max_value <- max(data$value[data$label == 'a']) 
    result <- c() 
    for (x in data$value){ 
     if (x == max_value){ 
      result <- c(result, data$second) 
     } 
    } 

Теперь это не создает правильный вектор результатов. Я хотел бы выяснить способ сделать это с помощью sapply, tapply, mapply и т. Д. У меня просто возникают проблемы с этим. Любая помощь будет принята с благодарностью.

ответ

2
lapply(split(dat, dat$label), 
     function(df) df[df$value == max(df$value), "second"]) 
$a 
[1] ASDF 
Levels: ASDF q QWERTY 

$b 
[1] QWERTY QWERTY 
Levels: ASDF q QWERTY 

$c 
[1] q 
Levels: ASDF q QWERTY 

$d 
[1] q 
Levels: ASDF q QWERTY 

Если вы хотите избавиться от багажа факторов:

lapply(split(dat, dat$label), 
    function(df) as.character(df[df$value == max(df$value), "second"])) 
$a 
[1] "ASDF" 

$b 
[1] "QWERTY" "QWERTY" 

$c 
[1] "q" 

$d 
[1] "q" 

Для извлечения конкретного листа, установить этот результат к значению и экстракция "[[":

val <- lapply(split(dat, dat$label), 
    function(df) as.character(df[df$value == max(df$value), "second"])) 
val[["a"]] 
#[1] "ASDF" 
+0

Спасибо очень много. Теперь, как я могу извлечь, скажем, вектор максимумов для фактора «b»? Это так же просто, как x <- lapply (...) x [2] ? – aridneptune

3

Прямо вперед в data.table:

library(data.table) 
DT <- data.table(df, key="label") 
DT[.(lab)][value==max(value), second] 

# where `lab` is whatever label value you are trying to find 

Обратите внимание, что если вы хотите сделать это для все значения label, просто использовать by аргумент:

DT[, c(.SD, mx=max(value)), by=label][value==mx, second, by=label] 

    label second 
1:  a ASDF 
2:  b QWERTY 
3:  b QWERTY 
4:  c  q 
5:  d  q 
1

Альтернативной функция base R:

df2 <- by(data = df, df$label, function(x) x[x$value == max(x$value), ]) 

# result as a list 
df2 
# df$label: a 
# value label second 
# 3  3  a ASDF 
# -------------------------------------------------------------------- 
# df$label: b 
# value label second 
# 5  6  b QWERTY 
# 6  6  b QWERTY 
# -------------------------------------------------------------------- 
# df$label: c 
# value label second 
# 9  9  c  q 
# -------------------------------------------------------------------- 
# df$label: d 
# value label second 
# 10 10  d  q 

# ...or as a data frame 
do.call(rbind, df2) 
#  value label second 
# a  3  a ASDF 
# b.5  6  b QWERTY 
# b.6  6  b QWERTY 
# c  9  c  q 
# d  10  d  q 
Смежные вопросы