【问题标题】:Subtracting similarly named elements in a list of vectors in R在R中的向量列表中减去类似命名的元素
【发布时间】:2019-12-14 10:59:36
【问题描述】:

我有一个包含 3 个向量的列表,XYZ。我想减去这 3 个向量的 类似名称 元素。也就是说,类似名称的元素会像这样被减去:X - Y - Z

另外,如果一个元素(这里是 ChandlerAX 中的 Trus.Hsu)在一个向量中只出现一次,而在其他向量中不出现,那么我想完全跳过该元素。

我的想要的输出是:

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

是否有可能在 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

【问题讨论】:

  • 类似i = intersect(names(V$X), intersect(names(V$Y), names(V$Z))); V$X[i] - (V$Y[i] + V$Z[i])?
  • 期望的输出是什么?
  • 我会分三步进行:1. 将列表更改为数据框 X、Y、Z 2. 基于名称的内部连接 ​​3. 进行减法。
  • @utubun 例如Bit.KnoA出现在XY中,所以Bit.KnoA出现在X中-Bit.KnoA出现在Y中。或者Bit.KnoB 出现在XYZ 中,所以Bit.KnoBX - Bit.KnoBY - Bit.KnoBZ。但ChandlerA 只出现在X 中,所以完全排除。
  • @utubun,我已经添加了我想要的输出。

标签: r list function lapply


【解决方案1】:

我们可以使用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 

或使用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 

【讨论】:

  • This question 你可能感兴趣?
  • @Reza 让我知道你什么时候可以在线进行疑难解答
【解决方案2】:

这是一个基本的 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 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-08
    • 2014-10-19
    • 1970-01-01
    • 2021-10-21
    • 2016-12-03
    • 2022-07-01
    • 2015-03-14
    相关资源
    最近更新 更多