"lapply" 在 R 中不适用于每个元素
"lapply" in R does not work for each element
test.data <- data.frame(a=seq(10),b=rep(seq(5),times=2),c=rep(seq(5),each=2))
test.data <- data.frame(lapply(test.data, as.character), stringsAsFactors = F)
test.ref <- data.frame(original=seq(10),name=letters[1:10])
test.ref <- data.frame(lapply(test.ref, as.character), stringsAsFactors = F)
test.match <- function (x) {
result = test.ref$name[which(test.ref$original == x)]
return(result)
}
> data.frame(lapply(test.data, test.match))
a b c
1 a a a
2 b b a
3 c c a
4 d d a
5 e e a
6 f a a
7 g b a
8 h c a
9 i d a
10 j e a
> lapply(test.data, test.match)
$a
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
$b
[1] "a" "b" "c" "d" "e"
$c
[1] "a"
大家好,
我正在学习使用 R 中的 apply 系列。但是,我被困在一个相当简单的练习中。以上是我的代码。我正在尝试使用 "test.match" 函数通过 "test.ref" 中的引用规则替换 "test.data" 中的所有元素。但是,如果我将最终结果转换为数据框,最后一列将不起作用。如果我将结果保留为列表,情况会更糟。
非常感谢您的帮助,
凯文
如评论中所述,您可能需要 match
:
do.test.match.df <- function(df, ref_df = test.ref){
res <- df
res[] <- lapply(df, function(x) ref_df$name[ match(x, ref_df$original) ])
return(res)
}
do.test.match.df(test.data)
这给出了
a b c
1 a a a
2 b b a
3 c c b
4 d d b
5 e e c
6 f a c
7 g b d
8 h c d
9 i d e
10 j e e
这是惯用的方式。 lapply
将始终 return 普通列表。 data.frame 是一种特殊的列表(列向量列表)。使用 res[] <- lapply(df, myfun)
,我们分配给 res
.
的列
由于所有列都相同 class,我建议使用矩阵而不是 data.frame。
test.mat <- as.matrix(test.data)
do.test.match <- function(mat, ref_df=test.ref){
res <- matrix(, nrow(mat), ncol(mat))
res[] <- ref_df$name[ match( c(mat), ref_df$original ) ]
return(res)
}
do.test.match(test.mat)
test.data <- data.frame(a=seq(10),b=rep(seq(5),times=2),c=rep(seq(5),each=2))
test.data <- data.frame(lapply(test.data, as.character), stringsAsFactors = F)
test.ref <- data.frame(original=seq(10),name=letters[1:10])
test.ref <- data.frame(lapply(test.ref, as.character), stringsAsFactors = F)
test.match <- function (x) {
result = test.ref$name[which(test.ref$original == x)]
return(result)
}
> data.frame(lapply(test.data, test.match))
a b c
1 a a a
2 b b a
3 c c a
4 d d a
5 e e a
6 f a a
7 g b a
8 h c a
9 i d a
10 j e a
> lapply(test.data, test.match)
$a
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j"
$b
[1] "a" "b" "c" "d" "e"
$c
[1] "a"
大家好,
我正在学习使用 R 中的 apply 系列。但是,我被困在一个相当简单的练习中。以上是我的代码。我正在尝试使用 "test.match" 函数通过 "test.ref" 中的引用规则替换 "test.data" 中的所有元素。但是,如果我将最终结果转换为数据框,最后一列将不起作用。如果我将结果保留为列表,情况会更糟。
非常感谢您的帮助,
凯文
如评论中所述,您可能需要 match
:
do.test.match.df <- function(df, ref_df = test.ref){
res <- df
res[] <- lapply(df, function(x) ref_df$name[ match(x, ref_df$original) ])
return(res)
}
do.test.match.df(test.data)
这给出了
a b c
1 a a a
2 b b a
3 c c b
4 d d b
5 e e c
6 f a c
7 g b d
8 h c d
9 i d e
10 j e e
这是惯用的方式。 lapply
将始终 return 普通列表。 data.frame 是一种特殊的列表(列向量列表)。使用 res[] <- lapply(df, myfun)
,我们分配给 res
.
由于所有列都相同 class,我建议使用矩阵而不是 data.frame。
test.mat <- as.matrix(test.data)
do.test.match <- function(mat, ref_df=test.ref){
res <- matrix(, nrow(mat), ncol(mat))
res[] <- ref_df$name[ match( c(mat), ref_df$original ) ]
return(res)
}
do.test.match(test.mat)