2015-01-19 6 views
1

У меня есть кадр данных со столбцами символов, скажем tdf <- data.frame(words=letters[1:4], words2=letters[5:8], word3=letters[9:12])Объединения переменного числа полех через data.frame, используя mapply

Я также соответствующий вектор с указанием последнего номера столбца, который будет использоваться для объединения слов в каждая строка, скажем, tcol <- c(3, 1, 1, 2)

Так, например, для четвертой строки выход должен быть "d h".

Я написал функцию, которая может обрабатывать слияние каждой строки

xyp <- function(x, y) do.call(paste, as.list(x[1:y])) 

, который работает, как ожидалось с for цикла

> y <- character(0) 
> for (x in 1:nrow(tdf)) y <- c(y, xyp(tdf[x, ], tcol[x])) 
> y 
[1] "a e i" "b"  "c"  "d h" 

Я хотел бы применить функцию по всему кадру данных без использования цикла for, но функция, указанная выше, не работает для этой цели.

> mapply(xyp, tdf, tcol) 
    words words2 word3 <NA> 
"a b c"  "e"  "i" "a b" 
Warning message: 
In mapply(xyp, tdf, tcol) : 
    longer argument not a multiple of length of shorter 

Я думаю, что понимаю ошибку, но не уверен, что я могу сделать, чтобы исправить это. Какие-либо предложения?

+2

'mapply' будет работать на столбцах data.frame, а не на строках. Поэтому вам нужно что-то вроде «mapply» (xyp, data.frame (t (tdf)), tcol) 'Я думаю. Однако это не идеально. – thelatemail

ответ

1

Как насчет

mapply(function(x, i) paste(x[1:i], collapse=" "), 
    split(as.matrix(tdf),row(tdf)), 
    tcol) 

Здесь мы используем split() нарезать data.frame в список строк, а не список столбцов, как это обычно бывает с data.frame.

+2

Или 'split (tdf, rownames (tdf))' - они должны быть уникальными в data.frame, поэтому он разделяет каждую строку. – thelatemail