是否有R函数将列表除以字符列表
Is there an R function to divide a list by a character list
我想将 5 个数据框(每个包含 3 列,1000 行)中的所有数字除以 5 个字符列表(1 个元素,1000 行)中的相应数字。例如:
mylist1 <- list(A=c(1,3),B=c(1,1),C=c(0,2))
characterlist1 <- strrep(c("5", "10"), 1 )
(1) mylist1 CharacterList1 Output
A B C L -> A B C
1 1 0 5 -> .2 .2 0
3 1 2 10 -> .3 .1 .2
mylist2 <- list(A=c(0,1),B=c(2,2),C=c(1,1))
characterlist2 <- strrep(c("10", "10"), 1 )
(2) mylist2 CharacterList2 Output
A B C L -> A B C
0 2 1 10 -> 0 .2 .1
1 2 1 10 -> .1 .2 .1
对于具有单列的数据框,我们可以这样做:
(3) for (j in 1:5) {
Y=get(paste0("DF",j))
Z=get(paste0("CharacterList",j))
Z <- as.numeric(Z)
Y <- as.vector(Y, mode = "numeric")
Q <- vector(mode = "numeric", length = length(Y))
for (i in 1:length(Y)) {Q[i] <- Z[i]/Y[i]}
有没有一种简单的方法也可以对多列执行此操作?
我已经完成 并将我的数据框转换为一个大列表,我当前的解决方案是:
(4) list2env(lapply(mget(ls(.GlobalEnv, pattern = "DF"), envir = .GlobalEnv), function(x){
lapply(x, as.numeric)}
), .GlobalEnv)
但是当我尝试将 (4) 的结果输入到 (3) 时,我收到“'list' 对象无法强制键入 'double'”错误。有什么我错过的吗?
根据描述,我们可以遍历 data.frame
的 list
并将每个数据集划分为 vector[=15] 的 unlist
ed list
=]
lapply(lst_df, function(dat) dat/unlist(lst1))
获取列表中的所有 'mylist' 和 'characterlist' 并使用 Map
对其进行计算。
list1 <- mget(ls(pattern = 'mylist\d+'))
charvec1 <- mget(ls(pattern = 'characterlist\d+'))
result <- Map(function(x, y) do.call(cbind, x)/as.numeric(y),list1,charvec1)
#$mylist1
# A B C
#[1,] 0.2 0.2 0.0
#[2,] 0.3 0.1 0.2
#$mylist2
# A B C
#[1,] 0.0 0.2 0.1
#[2,] 0.1 0.2 0.1
根据您的问题描述而不是(不匹配的)代码,您想要的是函数sweep
:
sweep(df, 1L, numbers, `/`)
这会将输入数据框中的每一列除以向量 numbers
。
需要
- 将每个数字列表转换为 data.frame(使用
as.data.frame
)。
- 将字符串转换为数字(使用
as.numeric
)。
如果您有多个 data.frames/number 向量,请通过 Map
:
执行上述操作
Map(sweep, df_list, 1L, numbers_list, list(`/`))
请注意扫描函数 (/
) 是如何放入此处的单例列表中的。这可以防止 Map
尝试将函数视为要迭代的输入列表(这会失败)。相反,它现在看到的是一个只有一个元素的列表,因此它会回收其中的内容。 margin 参数 (1L
) 也是如此。我们也可以将其放入单例列表中,但这不是必需的,因为 Map
自己注意到这不是列表输入,需要回收。
我想将 5 个数据框(每个包含 3 列,1000 行)中的所有数字除以 5 个字符列表(1 个元素,1000 行)中的相应数字。例如:
mylist1 <- list(A=c(1,3),B=c(1,1),C=c(0,2))
characterlist1 <- strrep(c("5", "10"), 1 )
(1) mylist1 CharacterList1 Output
A B C L -> A B C
1 1 0 5 -> .2 .2 0
3 1 2 10 -> .3 .1 .2
mylist2 <- list(A=c(0,1),B=c(2,2),C=c(1,1))
characterlist2 <- strrep(c("10", "10"), 1 )
(2) mylist2 CharacterList2 Output
A B C L -> A B C
0 2 1 10 -> 0 .2 .1
1 2 1 10 -> .1 .2 .1
对于具有单列的数据框,我们可以这样做:
(3) for (j in 1:5) {
Y=get(paste0("DF",j))
Z=get(paste0("CharacterList",j))
Z <- as.numeric(Z)
Y <- as.vector(Y, mode = "numeric")
Q <- vector(mode = "numeric", length = length(Y))
for (i in 1:length(Y)) {Q[i] <- Z[i]/Y[i]}
有没有一种简单的方法也可以对多列执行此操作?
我已经完成
(4) list2env(lapply(mget(ls(.GlobalEnv, pattern = "DF"), envir = .GlobalEnv), function(x){
lapply(x, as.numeric)}
), .GlobalEnv)
但是当我尝试将 (4) 的结果输入到 (3) 时,我收到“'list' 对象无法强制键入 'double'”错误。有什么我错过的吗?
根据描述,我们可以遍历 data.frame
的 list
并将每个数据集划分为 vector[=15] 的 unlist
ed list
=]
lapply(lst_df, function(dat) dat/unlist(lst1))
获取列表中的所有 'mylist' 和 'characterlist' 并使用 Map
对其进行计算。
list1 <- mget(ls(pattern = 'mylist\d+'))
charvec1 <- mget(ls(pattern = 'characterlist\d+'))
result <- Map(function(x, y) do.call(cbind, x)/as.numeric(y),list1,charvec1)
#$mylist1
# A B C
#[1,] 0.2 0.2 0.0
#[2,] 0.3 0.1 0.2
#$mylist2
# A B C
#[1,] 0.0 0.2 0.1
#[2,] 0.1 0.2 0.1
根据您的问题描述而不是(不匹配的)代码,您想要的是函数sweep
:
sweep(df, 1L, numbers, `/`)
这会将输入数据框中的每一列除以向量 numbers
。
需要
- 将每个数字列表转换为 data.frame(使用
as.data.frame
)。 - 将字符串转换为数字(使用
as.numeric
)。
如果您有多个 data.frames/number 向量,请通过 Map
:
Map(sweep, df_list, 1L, numbers_list, list(`/`))
请注意扫描函数 (/
) 是如何放入此处的单例列表中的。这可以防止 Map
尝试将函数视为要迭代的输入列表(这会失败)。相反,它现在看到的是一个只有一个元素的列表,因此它会回收其中的内容。 margin 参数 (1L
) 也是如此。我们也可以将其放入单例列表中,但这不是必需的,因为 Map
自己注意到这不是列表输入,需要回收。