簡體   English   中英

將一個R數據集中的列/行與另一個R數據集中的值相乘

[英]multiply columns/rows in one R dataset with values from another

我有以下兩個數據集:

Dataset1                                 Dataset2

Kingdom  P1  P2  P5  P6  P7  T4  T6      P1  P2  P5  P6  P7  T4  T6
Virus    5   4   4   5   5   3   3       3   4   4   2   1   1   6
Bacteria 3   3   4   6   1   2   1       
Animal   1   2   3   4   4   1   5     
etc.                                 

我需要將dataset1的每一列乘以dataset2中的相應值。 例如,dataset2中P1的值需要將dataset1中P1列的每一行乘以3.我在這里展示的只是我的數據的摘錄。 數據集1有數千個輸入。

如果這兩個數據集相乘,輸出將如下所示:

Kingdom  P1  P2  P5  P6  P7  T4  T6                    
Virus    15  16  16  10   5   3  18                      
Bacteria 9   12  16  12   1   2   6       
Animal   3   8   12   8   4   1  30     
etc. 

如何解決這個問題的任何想法將不勝感激! 謝謝。

我們可以使用mapply來乘以Dataset1Dataset2每一列。 Dataset2是最終輸出。

Dataset3 <- Dataset1
Dataset3[, -1]<- mapply(`*`, Dataset1[, -1], Dataset2)
Dataset3
#    Kingdom P1 P2 P5 P6 P7 T4 T6
# 1    Virus 15 16 16 10  5  3 18
# 2 Bacteria  9 12 16 12  1  2  6
# 3   Animal  3  8 12  8  4  1 30

數據

Dataset1 <- read.table(text = "Kingdom  P1  P2  P5  P6  P7  T4  T6
Virus    5   4   4   5   5   3   3       
Bacteria 3   3   4   6   1   2   1       
Animal   1   2   3   4   4   1   5",
                       header = TRUE, stringsAsFactors = FALSE)

Dataset2 <- read.table(text = "P1  P2  P5  P6  P7  T4  T6
                       3   4   4   2   1   1   6",
                       header = TRUE)

你可以使用apply

> do.call(rbind, apply(Dataset1[,-1], 1, "*", Dataset2))
  P1 P2 P5 P6 P7 T4 T6
1 15 16 16 10  5  3 18
2  9 12 16 12  1  2  6
3  3  8 12  8  4  1 30

Dataset1和數據Dataset2在@ www的答案中定義。

只做直接乘法。 這可能是最快的解決方案:

cbind(Dataset1[1],t(t(Dataset1[-1])*unlist(Dataset2)))
   Kingdom P1 P2 P5 P6 P7 T4 T6
1    Virus 15 16 16 10  5  3 18
2 Bacteria  9 12 16 12  1  2  6
3   Animal  3  8 12  8  4  1 30

你也可以做cbind(Dataset1[1],t(t(Dataset1[-1])*c(t(Dataset2))))

你也可以使用sweep

cbind(Dataset1[1],sweep(Dataset1[-1],2,unlist(Dataset2),"*"))

   Kingdom P1 P2 P5 P6 P7 T4 T6
1    Virus 15 16 16 10  5  3 18
2 Bacteria  9 12 16 12  1  2  6
3   Animal  3  8 12  8  4  1 30

一個選項是使用apply和array multiplication。

cbind(Dataset1[1], do.call(rbind, apply(Dataset1[-1], 1, function(x)(x*Dataset2[1,]))))

#    Kingdom P1 P2 P5 P6 P7 T4 T6
# 1    Virus 15 16 16 10  5  3 18
# 2 Bacteria  9 12 16 12  1  2  6
# 3   Animal  3  8 12  8  4  1 30

注意:上面的答案與@JilberUrbina的答案非常相似。

數據:

Dataset1 <- read.table(text =                                 
"Kingdom  P1  P2  P5  P6  P7  T4  T6      
Virus    5   4   4   5   5   3   3       
Bacteria 3   3   4   6   1   2   1       
Animal   1   2   3   4   4   1   5",
header = TRUE)


Dataset2 <- read.table(text =
"P1  P2  P5  P6  P7  T4  T6
3   4   4   2   1   1   6",
header = TRUE)

您可以使用for循環執行此操作,如果data1是您的第一個數據集而data2是第二個數據集,則:

for(i in 1:dim(data2)[2]){
      data1[,i] <- data1[,i]*data2
}

你可以使用dplyr和tidyr包來做到這一點。

我們假設這是您的數據集:

ds_1 <- read.table(header = TRUE, text = "Kingdom  P1  P2  P5  P6  P7  T4  T6
Virus    5   4   4   5   5   3   3 
Bacteria 3   3   4   6   1   2   1       
Animal   1   2   3   4   4   1   5")

   Kingdom P1 P2 P5 P6 P7 T4 T6
1    Virus  5  4  4  5  5  3  3
2 Bacteria  3  3  4  6  1  2  1
3   Animal  1  2  3  4  4  1  5

ds_2 <- read.table(header = TRUE, text = "P1  P2  P5  P6  P7  T4  T6
3   4   4   2   1   1   6")

  P1 P2 P5 P6 P7 T4 T6
1  3  4  4  2  1  1  6
  1. 使用tidyr的gather()從寬到長切換:

     ds_1 <- ds_1 %>% gather(Key, Value, -Kingdom) Kingdom Key Value 1 Virus P1 5 2 Bacteria P1 3 3 Animal P1 1 4 Virus P2 4 5 Bacteria P2 3 6 Animal P2 2 ... ds_2 <- ds_2 %>% gather(Key, Multiplier) Key Multiplier 1 P1 3 2 P2 4 3 P5 4 4 P6 2 ... 
  2. 現在,您可以使用dplyr的left_join()合並到兩個數據幀,並使用mutate()乘法:

     ds_1 %>% left_join(ds_2, by = "Key") %>% mutate(Value = Value * Multiplier) %>% select(-Multiplier) Kingdom Key Value 1 Virus P1 15 2 Bacteria P1 9 3 Animal P1 3 4 Virus P2 16 5 Bacteria P2 12 6 Animal P2 8 7 Virus P5 16 8 Bacteria P5 16 ... 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM