如何在存储在列表中的特定文本前面加上减号 [R]

How to put minus in front of specific texts stored in a list [R]

我有如下所示的列表:

name <- c("A","B","C","D","E")
n <- c("1, 2, 3, 4, 5", "6, 7, 8", "9, 10", "11, 12, 13, 14", "15, 16, 17")
type <- c("a", "b", "c", "d", "e")

list <- list(name=name, n=n, type=type)

> list
$name
[1] "A" "B" "C" "D" "E"

$n
[1] "1, 2, 3, 4, 5"  "6, 7, 8"        "9, 10"          "11, 12, 13, 14" "15, 16, 17"    

$type
[1] "a" "b" "c" "d" "e"

另一方面,我有另一个数据框:

df <- data.frame(
  name=c("A","A","A","A","A","B","B","B","C","C","D","D","D","D","E","E","E"),
n=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17),
yn=c("Yes","Yes","No","No","Yes","No","Yes","Yes","Yes","Yes","No","Yes","Yes","No","Yes","Yes","Yes"))

> df
   name  n  yn
1     A  1 Yes
2     A  2 Yes
3     A  3  No
4     A  4  No
5     A  5 Yes
6     B  6  No
7     B  7 Yes
8     B  8 Yes
9     C  9 Yes
10    C 10 Yes
11    D 11  No
12    D 12 Yes
13    D 13 Yes
14    D 14  No
15    E 15 Yes
16    E 16 Yes
17    E 17 Yes

如果数据框中对应的ynNo,我想把minus (-)放在list中存储的整数前面,如下所示:

有谁能实现这个操作吗? 这看起来有点奇怪,但我需要保留列表的结构。

非常感谢您的建议!!

基数 R:

sf <- function(y, x){
    z <- df$yn[which(df$n %in% as.numeric(y) & df$name == list$name[x])]
    y[which(z == "No")] <- paste0("-",y[which(z == "No")])
    return(y)
}

> list$n <- sapply(seq_along(list$n), function(x) {gsub(" -", "-", paste(sapply(strsplit(list$n[x], split = ", "), sf, x), collapse = ", "))})
> list
$name
[1] "A" "B" "C" "D" "E"

$n
[1] "1, 2,-3,-4, 5"   "-6, 7, 8"        "9, 10"           "-11, 12, 13,-14" "15, 16, 17"     

$type
[1] "a" "b" "c" "d" "e"

您可以试试下面的代码

list2DF(lst) %>%
  separate_rows(n, convert = TRUE) %>%
  left_join(df) %>%
  mutate(n = n * (2 * (yn == "Yes") - 1)) %>%
  group_by(name, type) %>%
  summarise(n = toString(n)) %>%
  ungroup() %>%
  as.list()

这给出了

$name
[1] "A" "B" "C" "D" "E"

$type
[1] "a" "b" "c" "d" "e"

$n
[1] "1, 2, -3, -4, 5"  "-6, 7, 8"         "9, 10"            "-11, 12, 13, -14"
[5] "15, 16, 17"

将数据放入dataframe,乘以yn的值,再次得到列表格式的数据。

library(dplyr)
library(tidyr)

bind_rows(list) %>%
  separate_rows(n, sep = ',\s*', convert = TRUE) %>%
  left_join(df, by = c('name', 'n')) %>%
  mutate(n = n * ifelse(yn == 'No', -1, 1)) %>%
  group_by(name, type) %>%
  summarise(n = toString(n), .groups = 'drop') %>%
  as.list()

#$name
#[1] "A" "B" "C" "D" "E"

#$type
#[1] "a" "b" "c" "d" "e"

#$n
#[1] "1, 2, -3, -4, 5"  "-6, 7, 8"         "9, 10"            "-11, 12, 13, -14" "15, 16, 17"