简体   繁体   English

在R中的向量列表中减去类似命名的元素

[英]Subtracting similarly named elements in a list of vectors in R

I have a list of 3 vectors, X , Y , and Z . 我有一个包含3个向量的列表, XYZ I want to subtract similarly named elements of these 3 vectors. 我想减去这3个向量中类似命名的元素。 That is, similarly named elements subtracted throughout like so: X - Y - Z . 也就是说,类似命名的元素如下所示减去: X - Y - Z

Also, if an element (here ChandlerA and Trus.Hsu in X ) appears only once in one vector but not in others, then I want to skip that element altogether. 此外,如果一个元素(此处为X ChandlerATrus.Hsu )在一个向量中只出现一次而在其他向量中不出现,那么我想完全跳过该元素。

My desired output is: 想要的输出是:

c(Bit.KnoA = -2, Bit.KnoB = -4, Bit.KnoC = -2, Ellis.etal = 3, Mubarak = 3, sheenA = 5, Shin.Ellis = 5, Sun = 7)

Is it possible to achieve this in Base R ? 是否有可能在Base R中实现这一目标?

V = list(X = c(Bit.KnoA = 4, Bit.KnoB = 1, Bit.KnoC = 2, ChandlerA = 3, Ellis.etal =4, 
               Mubarak=5, SheenA=6,  Shin.Ellis=7 , Sun = 8, Trus.Hsu=3 ), 

         Y = c(Bit.KnoA = 6, Bit.KnoB = 3, Bit.KnoC = 4, Ellis.etal =1, Mubarak=2, 
               SheenA=1,  Shin.Ellis=2 , Sun = 1),

         Z = c(Bit.KnoB = 2) )



V[[1]] - V[[2]] - V[[3]] # all elements regardless of names are subtracted

We can do this more compactly with aggregate and Reduce 我们可以使用aggregateReduce更紧凑地完成这项工作

with(aggregate(values ~ ind, subset(do.call(rbind, lapply(V, stack)), 
    ind %in% names(which(table(ind) > 1))), 
     FUN = function(x) Reduce(`-`, x)), setNames(values, ind))
#   Bit.KnoA   Bit.KnoB   Bit.KnoC Ellis.etal    Mubarak     SheenA Shin.Ellis        Sun 
#        -2         -4         -2          3          3          5          5          7 

or using tidyverse 或使用tidyverse

library(tidyverse)
map_df(V, enframe) %>% 
     group_by(name) %>% 
     filter(n() > 1) %>% 
     summarise(value = reduce(value, `-`)) %>%
     deframe
#   Bit.KnoA   Bit.KnoB   Bit.KnoC Ellis.etal    Mubarak     SheenA Shin.Ellis        Sun 
#        -2         -4         -2          3          3          5          5          7 

Here is one base R option 这是一个基本R选项

#Copy contents of V
V1 <- V
#Remove names of V1
names(V1) <- NULL
#unlist the values
vals <- unlist(V1)
#Find out names which occur only once
delete_names <- names(Filter(function(x) x == 1, table(names(vals))))
#Remove them from the list
new_vals <- vals[!names(vals) %in% delete_names]
#Subtract values from each similar named element.
sapply(unique(names(new_vals)), function(x) Reduce(`-`, new_vals[names(new_vals) == x]))

# Bit.KnoA   Bit.KnoB   Bit.KnoC Ellis.etal    Mubarak     SheenA Shin.Ellis        Sun 
#       -2         -4         -2          3          3          5          5          7 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM