我有一个来自非常大的数据集的数据子集。我已将此数据子集拆分为数据帧列表,以便每个案例/ID 都是列表中的单独元素。每个元素都以 case/id 命名。然后,我从每个数据帧元素中删除所有变量,只留下一个变量 - 称为“状态”。目前它是一个有 7 个级别的因子。
我正在尝试将这个“状态”元素列表转换为字符向量列表。下面的元素是列表中的第一个元素,其中包含行号(源自更大的原始数据集)。
[[1]]
state
104246 active
104247 rest
104248 active
104249 active
.
.
.
104315 active
104316 active
104317 rest
104318 rest
我试图将其简单地转换为如下所示的字符向量:
[1] "active" "rest" "active" "active" ........... "active" "active" "rest" "rest"
看起来很简单。我尝试过做类似的事情(其中“temp”是列表名称):
as.vector(as.matrix(temp))
这会返回类似这样的内容:
[,1]
id1 List,1
id2 List,1
id3 List,1
id4 List,1
当我查看其中的每个元素时,它们基本上看起来仍然是长格式。
或者,我尝试直接转换为字符:
as.vector(as.character(temp))
但是,这并不是理想的格式(不过,我想我可以破解它以将因子级别数字转换为单词......(注意在大数据集中,因子“状态”有 7 个级别)
[1] "list(state = c(1, 4, 1, 1, 1, 1, 1, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 1, 6, 1, 4, 4, 1, 1, 1, 4, 1, 1, 1, 6, 4, 1, 1, 1, 1, 1, 4, 4, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 1, 1, 1, 1, 4, 4, 1, 1, 1, 1, 1, 1, 1, 4, 4))"
我还尝试在转换之前将变量“状态”设置为字符变量,但这没有帮助。
这是可重现示例的数据。仅在本示例中,它包含列表“temp”中的两个元素:
temp<-list(structure(list(state = structure(c(1L, 4L, 1L, 1L, 1L, 1L,
1L, 4L, 4L, 4L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 4L, 4L, 1L,
6L, 1L, 4L, 4L, 1L, 1L, 1L, 4L, 1L, 1L, 1L, 6L, 4L, 1L, 1L, 1L,
1L, 1L, 4L, 4L, 1L, 4L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
4L, 4L, 4L, 4L, 1L, 1L, 1L, 1L, 4L, 4L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 4L, 4L), .Label = c("active", "active2", "active3", "rest", "rest2",
"stop", "stop2"), class = "factor")), .Names = "state", row.names = 104246:104318, class = "data.frame"),
structure(list(state = structure(c(1L, 4L, 4L, 4L, 1L, 1L,
1L, 4L, 4L, 4L, 4L, 1L, 4L, 4L, 4L, 1L, 1L, 6L, 4L, 1L, 4L,
4L, 4L, 1L, 4L, 1L, 1L, 1L), .Label = c("active", "active2",
"active3", "rest", "rest2", "stop", "stop2"), class = "factor")), .Names = "state", row.names = 950:977, class = "data.frame"))
str(temp)
这可能是一个使用
rapply
的好机会:
x <- rapply(temp, as.character, how = "replace")
str(x)
# List of 2
# $ :List of 1
# ..$ state: chr [1:73] "active" "rest" "active" "active" ...
# $ :List of 1
# ..$ state: chr [1:28] "active" "rest" "rest" "rest" ...
如果你想进一步展平它,那么你可以使用
unlist(..., recursive = FALSE)
。
str(unlist(rapply(temp, as.character, how = "replace"), recursive=FALSE))
# List of 2
# $ state: chr [1:73] "active" "rest" "active" "active" ...
# $ state: chr [1:28] "active" "rest" "rest" "rest" ...
第二种方法将为您提供与@Vlo 方法相同的结果,但比仅调用一次
unlist
更有效。为了看看它有多么不同,这里有一些更大的基准 list
:
x <- replicate(1000, temp) ## A larger list
## Vlo's approach
fun1 <- function() {
lapply(x, function(y) as.character(unlist(y, use.names = FALSE)))
}
## My approach
fun2 <- function() {
unlist(rapply(x, as.character, how = "replace"),
recursive=FALSE, use.names=FALSE)
}
## Benchmarking
library(microbenchmark)
microbenchmark(fun1(), fun2(), times = 50)
# Unit: milliseconds
# expr min lq median uq max neval
# fun1() 435.84992 475.17146 497.63325 533.68488 1570.6814 50
# fun2() 50.90449 55.79023 63.85908 70.78956 111.0357 50
## Comparison of results
all.equal(fun1(), fun2(), check.attributes=FALSE)
# [1] TRUE
L = lapply(temp, function(x) as.character(unlist(x)))
只需 L[[1]]
或 L[[2]]
表示向量。
尝试这段代码
as.vector(unlist(temp[[1]]))
使用以下代码:
temp1 = temp[[1]][[1]]
。这里,temp1
将是一个字符列表。
MWE:
abc = data.table(x = c('a', 'b', 'c'))
temp = list(abc[, 'x'])[[1]][[1]]
> temp
[1] "a" "b" "c"