在R中的列表中添加一些字符串

dzhpxtsq  于 2023-03-27  发布在  其他
关注(0)|答案(7)|浏览(204)

来自网页抓取的数据被保存到一个列表中。然而,有些元素并不是在每个页面上都可用,这导致列表具有不同长度的字符向量(如果所有数据都存在,则为4,如果所有数据都不存在,则为3)。
由于我需要保留列表的特定结构,所以我决定将相同的值附加到所有缺少数据的记录。
手动执行此操作是可行的,但是当尝试编写循环时,它最终会用附加的值替换缺失的值,从而导致长度为1的字符向量。
一些示例数据:

things <- list(c("red", "small", "expensive", "car"),
               c("big", "expensive", "bike"),
               c("green", "big", "cheap", "bike"),
               c("small", "expensive", "car"))

假设我们知道所有缺少第一条记录(颜色)的东西都是蓝色的,手动追加它就可以正常工作,例如,为第二条记录返回(“blue”“big”“expensive”“bike”)。

c("blue", things[[2]])

然而,试图将其转换为一个循环来遍历所有数据,基于字符长度的ifelse语句,它将整个向量替换为“blue”而不是追加它。

all_things <- list()

for(i in seq_along(things)) {
  all_things[i] <- ifelse(length(things[[i]]) == 3, c("blue", things[[i]]), things[i])
}

运行循环将返回:
1[1]“红”“小”“贵”“车”
2[1]“蓝色”
3[1]“绿色”“大”“便宜”“自行车”
4[1]“蓝色”
非常感谢你的帮助!

8gsdolmq

8gsdolmq1#

我会分两步来做:
1.在 all 列表项前添加“missing”值
1.只取每个列表项的最后4个值
这个两步过程意味着我们不需要使用ifelse,也不需要循环:

lapply(things, append, "blue", after = 0L) |> lapply(tail, 4L)

结果:

[[1]]
[1] "red"       "small"     "expensive" "car"

[[2]]
[1] "blue"      "big"       "expensive" "bike"

[[3]]
[1] "green" "big"   "cheap" "bike"

[[4]]
[1] "blue"      "small"     "expensive" "car"

这是非常罕见的情况之一,其中append而不是c是合适的(即使我们 prepend;再次显示append被错误命名)。

idfiyjo8

idfiyjo82#

如果使用base R,可以尝试lengths + Map

> things[lengths(things) == 3] <- Map(c, "blue", things[lengths(things) == 3])

> things
[[1]]
[1] "red"       "small"     "expensive" "car"

[[2]]
[1] "blue"      "big"       "expensive" "bike"

[[3]]
[1] "green" "big"   "cheap" "bike"

[[4]]
[1] "blue"      "small"     "expensive" "car"
r1zhe5dt

r1zhe5dt3#

你也可以用

purrr::map_at(things, lengths(things) == 3, ~c('blue', .x))

[[1]]
[1] "red"       "small"     "expensive" "car"      

[[2]]
[1] "blue"      "big"       "expensive" "bike"     

[[3]]
[1] "green" "big"   "cheap" "bike" 

[[4]]
[1] "blue"      "small"     "expensive" "car"
np8igboo

np8igboo4#

您可以使用lapply来检查您的条件,即

lapply(things, \(i) if(length(i) == 3) {c('blue', i)}else{i})

[[1]]
[1] "red"       "small"     "expensive" "car"      

[[2]]
[1] "blue"      "big"       "expensive" "bike"     

[[3]]
[1] "green" "big"   "cheap" "bike" 

[[4]]
[1] "blue"      "small"     "expensive" "car"
mccptt67

mccptt675#

library(tidyverse)

things <- list(c("red", "small", "expensive", "car"),
               c("big", "expensive", "bike"),
               c("green", "big", "cheap", "bike"),
               c("small", "expensive", "car"))

map(
  things,
  ~if (length(.x) == 3L) c("blue", .x) else .x
)
#> [[1]]
#> [1] "red"       "small"     "expensive" "car"      
#> 
#> [[2]]
#> [1] "blue"      "big"       "expensive" "bike"     
#> 
#> [[3]]
#> [1] "green" "big"   "cheap" "bike" 
#> 
#> [[4]]
#> [1] "blue"      "small"     "expensive" "car"

创建于2023-03-22带有reprex v2.0.2

yacmzcpb

yacmzcpb6#

您可以使用lapply循环并在每个长度为3的向量前面添加“blue”

things[lengths(things) == 3] <- lapply(things[lengths(things) == 3], \(x) c("blue", x))
things
#> [[1]]
#> [1] "red"       "small"     "expensive" "car"      
#> 
#> [[2]]
#> [1] "blue"      "big"       "expensive" "bike"     
#> 
#> [[3]]
#> [1] "green" "big"   "cheap" "bike" 
#> 
#> [[4]]
#> [1] "blue"      "small"     "expensive" "car"
6rqinv9w

6rqinv9w7#

你可以像这样修改你的代码:

all_things <- list()

for(i in seq_along(things)) {
  all_things[[i]] <- if(length(things[[i]]) == 3) c("blue", things[[i]]) else things[[i]]
}

这里我们使用[[代替[,使用if () {} else {}代替ifelse。您应该研究ifelse的文档。

相关问题