Как добавить столбцы в фрейм данных через lapply - PullRequest
1 голос
/ 21 февраля 2020

Есть несколько проблем, с которыми я столкнулся, нуждающихся в помощи:

, поэтому у меня есть такой tsvfile

intermediate.tsv
experiment control   par1 par2 par3
1          a_control  1    11   21 
1          b_control  5    12   21
2          a_control  2    11   50 
2          b_control  3    13   31
3          a_control  4    11   35
3          b_control  2    11   35

Я прочитал tsvfile так:

tsvfiles<- read.csv2('/path_location/intermediate.tsv', header=T, sep = '\t', stringsAsFactors = F)

преобразовать значение в число c

for(i in 3:ncol(tsvfiles)) {
  tsvfiles[,i] <- as.numeric(tsvfiles[, i])
}

Я понимаю, что когда я вызываю tsvfiles $ control, я получаю только 'a' или 'b', что не так уж сложно, но если кто-то может помогите мне исправить это будет здорово

Так как я просто хочу вызвать par * заголовок столбца, я установил переменную col

cols <- names(tsvfiles)[!names(tsvfiles) %in% c('experiment', 'control')]

Затем я хочу, чтобы мой первый столбец был таким :

final_data<- c('Description', 'a_control Mean', 'a_control sd',  'b_control Mean', 'b_control sd', 'plot')

И создать функцию

generate_table<-function(data, col){

  a_mean = mean(data[[col]][tsvfiles$control == "a"])
  b_mean = mean(data[[col]][tsvfiles$control == "b"])
  a_sd = sd(data[[col]][tsvfiles$control == "a"])
  b_sd = sd(data[[col]][tsvfiles$control == "b"])

  p1 <- ggplot(data, aes(x=control, y= !!sym(col), color = control)) + 
    geom_violin() + geom_boxplot(width = 0.1)  +
    geom_jitter(shape = 16, colour = "black", alpha = 0.5, width = 0.2) +
    scale_x_discrete(limits = rev(levels(as.factor(data$control)))) +
    coord_flip()
  column <- c(col, a_mean, a_sd, b_mean, b_sd)
  return(column)
}

, когда я делаю лапы

lapply(cols, generate_table, data=tsvfiles)

Я получаю каждый из этих

"par1"            "1.15285714285714"   "0.0543270519302177" "1.2055"             "0.0730879066964102" 
"par2"            "11.15285714285714"   "1.0543270519302177" "12.2055"             "3.0730879066964102" 
"par3"            "31.15285714285714"   "5.0543270519302177" "21.2055"             "2.0730879066964102" 

Теперь вот реальный вопрос

как применить вывод из lapply и добавить его к final_data, как это

Description     par1                par2               par3
a_mean     1.15285714285714   11.15285714285714   31.15285714285714
a_sd       0.0543270519302177 1.0543270519302177  5.0543270519302177
b_mean     1.2055             12.2055             21.2055
b_sd       0.0730879066964102 3.0730879066964102  2.0730879066964102

Это раньше, даже не имея строки графика, которую я пробовал

final_data = cbind(final_data , lapply(cols, generate_table, data=tsvfiles))

и я не могу получить в final_data все столбцы из функции,

Спасибо

1 Ответ

2 голосов
/ 21 февраля 2020

Избегайте зацикливания с lapply и рассмотрите aggregate после преобразования ваших широких данных в длинный формат с reshape. Длинные или аккуратные данные обычно являются предпочтительным форматом в большинстве аналитических данных, облегчая процессы агрегации, слияния, добавления и построения графиков и моделирования. Кроме того, избегая многократного запуска графиков и рассмотрите facet_wrap в нужном измерении.

# RESHAPE WIDE TO LONG
tsv_long_df <- reshape(tsvfiles, varying = names(tsvfiles)[3:ncol(tsvfiles)],
                       times = names(tsvfiles)[3:ncol(tsvfiles)],
                       v.names = "value", timevar = "par", ids = NULL,
                       new.row.names = 1:1E4, direction = "long")    
head(tsv_long_df)
#   experiment   control  par value
# 1          1 a_control par1     1
# 2          1 b_control par1     5
# 3          2 a_control par1     2
# 4          2 b_control par1     3
# 5          3 a_control par1     4
# 6          3 b_control par1     2

# AGGREGATE WITH MERGE FOR BOTH CONTROLS
agg_raw <- merge(aggregate(value ~ par, subset(tsv_long_df, control == "a_control"), 
                           FUN=function(x) c(mean=mean(x), sd=sd(x))),
                 aggregate(value ~ par, subset(tsv_long_df, control == "b_control"), 
                           FUN=function(x) c(mean=mean(x), sd=sd(x))),
                 by="par", suffixes=c("_a", "_b"))

agg_df <- do.call(data.frame, agg_raw)   

Вывод

# DATA FRAME
agg_df <- setNames(agg_df, gsub("value_", "", names(agg_df)))
agg_df                         
#    par    a.mean      a.sd    b.mean      b.sd
# 1 par1  2.333333  1.527525  3.333333  1.527525
# 2 par2 11.000000  0.000000 12.000000  1.000000
# 3 par3 35.333333 14.502873 29.000000  7.211103

# MATRIX (TRANSPOSED FROM ABOVE)
agg_mat <- setNames(data.frame(t(agg_df[-1])), agg_df$par)
agg_mat
#            par1 par2      par3
# a.mean 2.333333   11 35.333333
# a.sd   1.527525    0 14.502873
# b.mean 3.333333   12 29.000000
# b.sd   1.527525    1  7.211103

Онлайн-демонстрация (с использованием опубликованных данных)


Участок (один вызов с использованием длинных данных с facet_wrap)

ggplot(tsv_long_df, aes(x=control, y=value, color = control)) + 
  geom_violin() + geom_boxplot(width = 0.1)  +
  geom_jitter(shape = 16, colour = "black", alpha = 0.5, width = 0.2) +
  coord_flip() + facet_wrap(~par, ncol=1)

Plot Output

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...