#r #function
#r #функция
Вопрос:
Например, давайте использовать следующий фрейм данных, состоящий из строк:
df <- data.frame(X = LETTERS[1:3], Y = LETTERS[4:6], row.names = c("r1", "r2", "r3"), stringsAsFactors = F)
> df
X Y
r1 A D
r2 B E
r3 C F
Теперь я хотел бы применить эту функцию к каждому элементу фрейма данных:
my_f <- function(x) paste0(x, x)
Что должно привести к такому результату:
>df
X Y
r1 AA DD
r2 BB EE
r3 CC FF
Я использовал вложенные циклы for:
for (i in 1:dim(df)[1]) {
for (j in 1:dim(df)[2]) {
df[i, j] = my_f(df[i, j])
}
}
Интересно, есть ли более короткий / быстрый способ добиться того же результата? Обратите внимание, что результатом должен быть фрейм данных с теми же именами строк и столбцов.
Ответ №1:
Мы можем использовать strrep
, перебирая столбцы dataset с lapply
помощью . []
Это восстановит ту же структуру ‘data.frame’.
df[] <- lapply(df, strrep,2)
df
# X Y
#r1 AA DD
#r2 BB EE
#r3 CC FF
Комментарии:
1. @agenis Да, я думаю
strrep
, должно быть быстрее2. Не могли бы вы объяснить разницу между
df
иdf[]
? Если я используюdf[]<-apply(df,2,my_f)
его, он работает, но без[]
него теряются имена строк.
Ответ №2:
Вот решение без какой-либо apply-функции:
df[] <- my_f(as.matrix(df))
Ответ №3:
У вас уже есть ответ.
Вы можете apply
использовать свою функцию my_f
для каждого элемента rowwise ( margin = 1
)
data.frame(t(apply(df, 1,my_f)))
# X1 X2
#r1 AA DD
#r2 BB EE
#r3 CC FF
И, как предложил @m0h3n, вы можете избежать t
шага ранспозиции, применив функцию по столбцам ( margin=2
)
data.frame(apply(df, 2,my_f))
Комментарии:
1. Если вы выберете
margin=2
, вам не нужно будет переносить.2. Просто примечание, только это решение не требует
df[] <-
присваивания для созданияdata.frame
, т. Е. Вы можете сделатьnew_df <- apply(df, 2, my_f)
.
Ответ №4:
Использование циклов for
for(i in 1:nrow(df)){
df$X[i] <- paste0(df$X[i],df$X[i],collapse = "")
df$Y[i] <- paste0(df$Y[i],df$Y[i],collapse = "")
}
print(df)
X Y
r1 AA DD
r2 BB EE
r3 CC FF