Tüm değerleri referans satırına böl

Dec 15 2020

Buna benzer görünse de bu , ben bir "düzenli" bir çözüm arıyorum ...

Aşağıdaki verilere bakalım (merak ediyorsanız, bazı kimyasal elementler için kaya bileşimleri):

# A tibble: 4 x 15
  Rock        La     Ce     Pr     Nd    Sm    Eu    Gd     Tb    Dy     Ho    Er     Tm    Yb     Lu
  <chr>      <dbl>  <dbl>  <dbl>  <dbl> <dbl> <dbl> <dbl>  <dbl> <dbl>  <dbl> <dbl>  <dbl> <dbl>  <dbl>
1 Upper CC  31     63     7.1    27     4.7   1     4     0.7    3.9   0.83   2.3   0.3    1.96  0.31  
2 Middle CC 24     53     5.8    25     4.6   1.4   4     0.7    3.8   0.82   2.3   0.32   2.2   0.4   
3 Lower CC   8     20     2.4    11     2.8   1.1   3.1   0.48   3.1   0.68   1.9   0.24   1.5   0.25  
4 chondrite  0.235  0.603 0.0891  0.452 0.147 0.056 0.197 0.0363 0.243 0.0556 0.159 0.0242 0.162 0.0243

(dput için sonuna bakın)

Bu, üç örnek ve bir referans değerden (kondrit) oluşur. Her bir elementin değerini her örnek için kondrite göre normalleştirmek istiyorum, yani şöyle bir şey elde etmek istiyorum:

# A tibble: 4 x 15
  Rock         La    Ce    Pr    Nd    Sm    Eu    Gd    Tb    Dy    Ho    Er    Tm    Yb    Lu
  <chr>     <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 Upper CC  132.  104.   79.7  59.7  32.0  17.9  20.3  19.3  16.0  14.9  14.5 12.4  12.1   12.8
2 Middle CC 102.   87.9  65.1  55.3  31.3  25    20.3  19.3  15.6  14.8  14.5 13.2  13.6   16.5
3 Lower CC   34.0  33.2  26.9  24.3  19.0  19.6  15.7  13.2  12.8  12.2  12.0  9.92  9.26  10.3
4 chondrite   1     1     1     1     1     1     1     1     1     1     1    1     1      1

Burada, tabii ki, df ["Üst CC", "La"] için ilk 132, 31 / 0.235'ten gelir, yani df ["Üst CC", "La"] / df ["kondrit", "La"]

Bu, excel'de önemsizdir ve düz R'de şu satırlarda bir şeyle yapılabilir:

apply(df[,-1],1,FUN=function(z){return(z/df[4,-1])})

Unlist () ve diğer nitelikleri verin veya alın.

Ama bunu daha düzenli bir deyimle nasıl yaparım? İnşa etmeye başladım

df %>% mutate(across( where(is.numeric), ... ? .... ) )

... ama daha ileri gidemedi.

Genelleştir / ilgili soru: df [4,] ile normalleştirmek yerine, rastgele adlandırılmış bir vektör ile normalleştir.

dput(df)

structure(list(Rock = c("Upper CC", "Middle CC", "Lower CC", 
"chondrite"), La = c(31, 24, 8, 0.2347), Ce = c(63, 53, 20, 0.6032
), Pr = c(7.1, 5.8, 2.4, 0.0891), Nd = c(27, 25, 11, 0.4524), 
    Sm = c(4.7, 4.6, 2.8, 0.1471), Eu = c(1, 1.4, 1.1, 0.056), 
    Gd = c(4, 4, 3.1, 0.1966), Tb = c(0.7, 0.7, 0.48, 0.0363), 
    Dy = c(3.9, 3.8, 3.1, 0.2427), Ho = c(0.83, 0.82, 0.68, 0.0556
    ), Er = c(2.3, 2.3, 1.9, 0.1589), Tm = c(0.3, 0.32, 0.24, 
    0.0242), Yb = c(1.96, 2.2, 1.5, 0.1625), Lu = c(0.31, 0.4, 
    0.25, 0.0243)), row.names = c(NA, -4L), class = c("tbl_df", 
"tbl", "data.frame"))

Yanıtlar

1 RonakShah Dec 15 2020 at 20:01

Kullanabilirsiniz :

library(dplyr)

df %>% mutate(across(where(is.numeric), ~./.[Rock == "chondrite"]))

#   Rock     La    Ce    Pr    Nd    Sm    Eu    Gd    Tb    Dy
#  <chr>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 Upper … 132.  104.   79.7  59.7  32.0  17.9  20.3  19.3  16.1
#2 Middle… 102.   87.9  65.1  55.3  31.3  25.0  20.3  19.3  15.7
#3 Lower …  34.1  33.2  26.9  24.3  19.0  19.6  15.8  13.2  12.8
#4 chondr…   1     1     1     1     1     1     1     1     1  
# … with 5 more variables: Ho <dbl>, Er <dbl>, Tm <dbl>,
#   Yb <dbl>, Lu <dbl>
1 jay.sf Dec 15 2020 at 20:03

Matris hesaplamalarını kullanma.

m <- t(dat[-1])
dat[-1] <- t(m / m[,4])
# Rock        La        Ce       Pr       Nd       Sm       Eu       Gd       Tb       Dy       Ho       Er        Tm        Yb       Lu
# 1  Upper CC 131.91489 104.47761 79.68575 59.73451 31.97279 17.85714 20.30457 19.28375 16.04938 14.92806 14.46541 12.396694 12.098765 12.75720
# 2 Middle CC 102.12766  87.89386 65.09540 55.30973 31.29252 25.00000 20.30457 19.28375 15.63786 14.74820 14.46541 13.223140 13.580247 16.46091
# 3  Lower CC  34.04255  33.16750 26.93603 24.33628 19.04762 19.64286 15.73604 13.22314 12.75720 12.23022 11.94969  9.917355  9.259259 10.28807
# 4 chondrite   1.00000   1.00000  1.00000  1.00000  1.00000  1.00000  1.00000  1.00000  1.00000  1.00000  1.00000  1.000000  1.000000  1.00000

Veri

dat <- structure(list(Rock = c("Upper CC", "Middle CC", "Lower CC", 
"chondrite"), La = c(31, 24, 8, 0.235), Ce = c(63, 53, 20, 0.603
), Pr = c(7.1, 5.8, 2.4, 0.0891), Nd = c(27, 25, 11, 0.452), 
    Sm = c(4.7, 4.6, 2.8, 0.147), Eu = c(1, 1.4, 1.1, 0.056), 
    Gd = c(4, 4, 3.1, 0.197), Tb = c(0.7, 0.7, 0.48, 0.0363), 
    Dy = c(3.9, 3.8, 3.1, 0.243), Ho = c(0.83, 0.82, 0.68, 0.0556
    ), Er = c(2.3, 2.3, 1.9, 0.159), Tm = c(0.3, 0.32, 0.24, 
    0.0242), Yb = c(1.96, 2.2, 1.5, 0.162), Lu = c(0.31, 0.4, 
    0.25, 0.0243)), class = "data.frame", row.names = c("1", 
"2", "3", "4"))
1 akrun Dec 15 2020 at 23:24

Kullanma data.table

library(data.table)
setDT(df1)[, (names(df1)[-1]) := lapply(.SD, function(x) 
       x/x[match( "chondrite", Rock)]), .SDcols = -1]