Объединение нескольких фреймов данных по столбцам в R

#r

#r

Вопрос:

[R новичок!]Заголовок может создать впечатление избыточного вопроса; однако мое исследование не смогло дать ответ; поэтому я публикую это. У меня есть три фрейма данных с размерами [9,9], и я с нетерпением жду возможности объединить (т. Е. Вставить, А НЕ объединить / объединить / связать / связать / связать) Три по столбцам, чтобы создать новый фрейм данных с размерами [9,9].

Фреймы данных являются:

df1.

 head(asian.te, 3)
#>   Cana100mg Cana200mg Dapa10mg Dapa5mg Ipra50mg Placebo Tofo10mg Tofo20mg Tofo40mg
#> 1      0.00      0.02    -0.21   -0.28     0.22   -1.03   -0.261   -0.041   -0.188
#> 2     -0.02      0.00    -0.23   -0.30     0.20   -1.05   -0.281   -0.061   -0.208
#> 3      0.21      0.23     0.00   -0.07     0.43   -0.82   -0.051    0.169    0.022
  

df2.

 head(lower.asian, 3)
#>   Cana100mg Cana200mg Dapa10mg Dapa5mg Ipra50mg Placebo Tofo10mg Tofo20mg Tofo40mg
#> 1     0.000    -0.001   -0.399  -0.476   -0.001  -1.050   -0.493   -0.272   -0.419
#> 2    -0.041     0.000   -0.419  -0.496   -0.021  -1.070   -0.513   -0.292   -0.439
#> 3     0.021     0.041    0.000  -0.261    0.141  -1.007   -0.349   -0.128   -0.275  
  

df3.

 head(upper.asian,3)
#>   Cana100mg Cana200mg Dapa10mg Dapa5mg Ipra50mg Placebo Tofo10mg Tofo20mg Tofo40mg
#> 1     0.000     0.041   -0.021  -0.084    0.441  -1.010   -0.029    0.190    0.043
#> 2     0.001     0.000   -0.041  -0.104    0.421  -1.030   -0.049    0.170    0.023
#> 3     0.399     0.419    0.000   0.121    0.719  -0.633    0.247    0.466    0.319
  

То, что я ищу, — это следующий вывод для всех столбцов трех фреймов данных:

 data.frame(Cana100mg = paste0(asian.te$Cana100mg, "(", lower.asian$Cana100mg, ", ", upper.asian$Cana100mg, ")"),
           Cana200mg = paste0(asian.te$Cana200mg, "(", lower.asian$Cana200mg, ", ", upper.asian$Cana200mg, ")"),
           Dapa10mg  = paste0(asian.te$Dapa10mg, "(", lower.asian$Dapa10mg, ", ", upper.asian$Dapa10mg, ")"))

#>              Cana100mg            Cana200mg              Dapa10mg
#> 1              0(0, 0)  0.02(-0.001, 0.041) -0.21(-0.399, -0.021)
#> 2 -0.02(-0.041, 0.001)              0(0, 0) -0.23(-0.419, -0.041)
#> 3   0.21(0.021, 0.399)   0.23(0.041, 0.419)               0(0, 0)
  

Однако я не считаю, что это эффективный код. Я ищу решение, которое может зацикливать одну строку кода «вставить» во все переменные трех фреймов данных. Может ли это быть достигнуто с помощью apply семейства функций? Я пытался использовать for, но не получил желаемого результата. Я считаю, что я не пишу правильный код и даже не могу самостоятельно разобраться в проблеме из-за отсутствия опыта.

 i <- 1
null.df <- data.frame(Cana100mg = character(9), Cana200mg = character(9), Dapa10mg = character(9),
           Dapa5mg = character(9), Ipra50mg = character(9), Placebo = character(9),
           Tofo10mg = character(9), Tofo20mg = character(9), Tofo40mg = character(9))

for (i in dim(asian.te)[1]) {
        null.df[,i] <- paste0(asian.te[,i], "(", lower.asian[,i], ", ", upper.asian[,i], ")")
        i <- i 1
       print(null.df)
}

#>   Cana100mg Cana200mg Dapa10mg Dapa5mg Ipra50mg Placebo Tofo10mg Tofo20mg             Tofo40mg
#> 1                                                                         -0.188(-0.272, 0.19)
#> 2                                                                         -0.208(-0.292, 0.17)
#> 3                                                                         0.022(-0.128, 0.466)
  

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

Комментарии:

1. ПРИМЕЧАНИЕ: последний вывод null.df содержит 9 строк, я обрезал печатный фрейм данных до 3 строк.

2. Вы должны иметь for(i in seq(ncols(asian.te)))... remove the i<-i 1

3. @Onyambu спасибо за помощь! Я понял, что происходит не так.

Ответ №1:

Это то, что вы ищете?

 as.data.frame(Map(function(te, lb, ub) {
  paste0(te, "(", lb, ",", ub, ")")
}, asian.te, lower.asian, upper.asian))
  

Комментарии:

1. Map sprintf будет намного чище data.frame(Map(sprintf, df_te, df_upper, df_lower, fmt = '%.2f(%.3f, %.3f)'))

2. @ekoam и @Onyambu благодарим вас обоих за быструю и эффективную помощь. Ваши коды выдали именно то, что я ожидал, я понятия не имею, хотя о Map sprintf функциях or, читая сейчас. Не могли бы вы также прокомментировать, почему for цикл, который я написал, не дал желаемых результатов?

Ответ №2:

Вероятно, вы сначала захотите преобразовать свои данные в длинную форму, что-то вроде этого:

 library(tidyverse)
library(glue)

df_te <- tibble(
  Cana100mg = c(0, -0.02, 0.21),
  Cana200mg = c(0.02, 0, 0.23),
  Dapa10mg = c(-0.21, -0.23, 0)
)
df_lower <- tibble(
  Cana100mg = c(0, -0.041, 0.021),
  Cana200mg = c(-0.001, 0, 0.041),
  Dapa10mg = c(-0.399, -0.419, 0)
)
df_upper <- tibble(
  Cana100mg = c(0, 0.001, 0.399),
  Cana200mg = c(0.041, 0, 0.419),
  Dapa10mg = c(-0.021, -0.041, 0)
)

df_te <- df_te %>% mutate(var = "te", id = 1:n())
df_lower <- df_lower %>% mutate(var = "lower", id = 1:n())
df_upper <- df_lower %>% mutate(var = "upper", id = 1:n())

df <- bind_rows(
  df_te,
  df_lower,
  df_upper
)

df
#> # A tibble: 9 x 5
#>   Cana100mg Cana200mg Dapa10mg var      id
#>       <dbl>     <dbl>    <dbl> <chr> <int>
#> 1     0         0.02    -0.21  te        1
#> 2    -0.02      0       -0.23  te        2
#> 3     0.21      0.23     0     te        3
#> 4     0        -0.001   -0.399 lower     1
#> 5    -0.041     0       -0.419 lower     2
#> 6     0.021     0.041    0     lower     3
#> 7     0        -0.001   -0.399 upper     1
#> 8    -0.041     0       -0.419 upper     2
#> 9     0.021     0.041    0     upper     3

df2 <- df %>% 
  pivot_longer(-c(var, id))

df2
#> # A tibble: 27 x 4
#>    var      id name      value
#>    <chr> <int> <chr>     <dbl>
#>  1 te        1 Cana100mg  0   
#>  2 te        1 Cana200mg  0.02
#>  3 te        1 Dapa10mg  -0.21
#>  4 te        2 Cana100mg -0.02
#>  5 te        2 Cana200mg  0   
#>  6 te        2 Dapa10mg  -0.23
#>  7 te        3 Cana100mg  0.21
#>  8 te        3 Cana200mg  0.23
#>  9 te        3 Dapa10mg   0   
#> 10 lower     1 Cana100mg  0   
#> # … with 17 more rows

df3 <- df2 %>% 
  separate(name, c("medicine", "dose"), sep = 4)
df3
#> # A tibble: 27 x 5
#>    var      id medicine dose  value
#>    <chr> <int> <chr>    <chr> <dbl>
#>  1 te        1 Cana     100mg  0   
#>  2 te        1 Cana     200mg  0.02
#>  3 te        1 Dapa     10mg  -0.21
#>  4 te        2 Cana     100mg -0.02
#>  5 te        2 Cana     200mg  0   
#>  6 te        2 Dapa     10mg  -0.23
#>  7 te        3 Cana     100mg  0.21
#>  8 te        3 Cana     200mg  0.23
#>  9 te        3 Dapa     10mg   0   
#> 10 lower     1 Cana     100mg  0   
#> # … with 17 more rows

df4 <- df3 %>% 
  pivot_wider(c(medicine, dose, id), names_from = var, values_from = value)

df4
#> # A tibble: 9 x 6
#>   medicine dose     id    te  lower  upper
#>   <chr>    <chr> <int> <dbl>  <dbl>  <dbl>
#> 1 Cana     100mg     1  0     0      0    
#> 2 Cana     200mg     1  0.02 -0.001 -0.001
#> 3 Dapa     10mg      1 -0.21 -0.399 -0.399
#> 4 Cana     100mg     2 -0.02 -0.041 -0.041
#> 5 Cana     200mg     2  0     0      0    
#> 6 Dapa     10mg      2 -0.23 -0.419 -0.419
#> 7 Cana     100mg     3  0.21  0.021  0.021
#> 8 Cana     200mg     3  0.23  0.041  0.041
#> 9 Dapa     10mg      3  0     0      0

df4 %>% 
  mutate(res = glue("{te} ({lower}, {upper}) "))
#> # A tibble: 9 x 7
#>   medicine dose     id    te  lower  upper res                      
#>   <chr>    <chr> <int> <dbl>  <dbl>  <dbl> <glue>                   
#> 1 Cana     100mg     1  0     0      0     "0 (0, 0) "              
#> 2 Cana     200mg     1  0.02 -0.001 -0.001 "0.02 (-0.001, -0.001) " 
#> 3 Dapa     10mg      1 -0.21 -0.399 -0.399 "-0.21 (-0.399, -0.399) "
#> 4 Cana     100mg     2 -0.02 -0.041 -0.041 "-0.02 (-0.041, -0.041) "
#> 5 Cana     200mg     2  0     0      0     "0 (0, 0) "              
#> 6 Dapa     10mg      2 -0.23 -0.419 -0.419 "-0.23 (-0.419, -0.419) "
#> 7 Cana     100mg     3  0.21  0.021  0.021 "0.21 (0.021, 0.021) "   
#> 8 Cana     200mg     3  0.23  0.041  0.041 "0.23 (0.041, 0.041) "   
#> 9 Dapa     10mg      3  0     0      0     "0 (0, 0) "
  

Создано 2020-11-16 пакетом reprex (версия 0.3.0)