R语言中使用管道符(%>%)结合paste0处理iris数据集的问题
解决iris数据集构造指定字符串向量的问题
我希望从iris数据集构造如下格式的字符串向量:c("speciesvalue1 Sepal.lengthvalue1", "speciesvalue2 Sepal.lengthvalue2","speciesvalue3 Sepal.lengthvalue3"...etc.)
同时仅保留Sepal.Width > 3的观测。
我原本想用管道符实现,代码如下:
iris %>% filter(Sepal.Width > 3) %>% paste0(.$Species," ",.$Sepal.Length)
但第二个管道会把整个数据框作为第一个参数传入paste0,得到错误输出:
[1] "c(5.1, 4.7, 4.6, 5, 5.4, 4.6, 5, 4.9, 5.4, 4.8, 5.8, 5.7, 5.4, 5.1, 5.7, 5.1, 5.4, 5.1, 4.6, 5.1, 4.8, 5, 5.2, 5.2, 4.7, 4.8, 5.4, 5.2, 5.5, 4.9, 5, 5.5, 4.9, 5.1, 5, 4.4, 5, 5.1, 5.1, 4.6, 5.3, 5, 7, 6.4, 6.9, 6.3, 6.7, 5.9, 6, 6.7, 6.3, 7.2, 6.5, 6.4, 7.7, 6.9, 6.7, 7.2, 7.9, 6.3, 6.4, 6.9, 6.7, 6.9, 6.8, 6.7, 6.2)setosa 5.1" [2] "c(3.5, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 3.1, 3.7, 3.4, 4, 4.4, 3.9, 3.5, 3.8, 3.8, 3.4, 3.7, 3.6, 3.3, 3.4, 3.4, 3.5, 3.4, 3.2, 3.1, 3.4, 4.1, 4.2, 3.1, 3.2, 3.5, 3.6, 3.4, 3.5, 3.2, 3.5, 3.8, 3.8, 3.2, 3.7, 3.3, 3.2, 3.2, 3.1, 3.3, 3.1, 3.2, 3.4, 3.1, 3.3, 3.6, 3.2, 3.2, 3.8, 3.2, 3.3, 3.2, 3.8, 3.4, 3.1, 3.1, 3.1, 3.1, 3.2, 3.3, 3.4)setosa 4.7" [3] "c(1.4, 1.3, 1.5, 1.4, 1.7, 1.4, 1.5, 1.5, 1.5, 1.6, 1.2, 1.5, 1.3, 1.4, 1.7, 1.5, 1.7, 1.5, 1, 1.7, 1.9, 1.6, 1.5, 1.4, 1.6, 1.6, 1.5, 1.5, 1.4, 1.5, 1.2, 1.3, 1.4, 1.5, 1.3, 1.3, 1.6, 1.9, 1.6, 1.4, 1.5, 1.4, 4.7, 4.5, 4.9, 4.7, 4.4, 4.8, 4.5, 4.7, 6, 6.1, 5.1, 5.3, 6.7, 5.7, 5.7, 6, 6.4, 5.6, 5.5, 5.4, 5.6, 5.1, 5.9, 5.7, 5.4)setosa 4.6" [4] "c(0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.1, 0.2, 0.2, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.3, 0.2, 0.6, 0.4, 0.2, 0.2, 0.2, 0.2, 1.4, 1.5, 1.5, 1.6, 1.4, 1.8, 1.6, 1.5, 2.5, 2.5, 2, 2.3, 2.2, 2.3, 2.1, 1.8, 2, 2.4, 1.8, 2.1, 2.4, 2.3, 2.3, 2.5, 2.3)setosa 5" ...
错误原因
管道符默认会把左侧的整个数据框作为第一个参数传给右侧函数,而paste0接收数据框时会将其强制转换为字符形式(也就是输出里的c(...)结构),再和.$Species、.$Sepal.Length拼接,最终得到不符合预期的结果。
可行解决方案
方法1:用mutate生成列后提取
先通过mutate创建目标字符串列,再用pull提取为向量:
iris %>% filter(Sepal.Width > 3) %>% mutate(result = paste0(Species, " ", Sepal.Length)) %>% pull(result)
方法2:用rowwise按行处理
让数据框按行执行paste0操作:
iris %>% filter(Sepal.Width > 3) %>% rowwise() %>% mutate(result = paste0(Species, " ", Sepal.Length)) %>% pull(result)
方法3:用with包裹paste0
通过with直接在过滤后的数据框环境中引用列名:
iris %>% filter(Sepal.Width > 3) %>% with(paste0(Species, " ", Sepal.Length))
方法4:提取列后直接拼接
先保存过滤结果,再提取列进行拼接:
filtered_iris <- iris %>% filter(Sepal.Width > 3) paste0(filtered_iris$Species, " ", filtered_iris$Sepal.Length)
内容的提问来源于stack exchange,提问作者Aku-Ville Lehtimäki
相关产品推荐
相关产品推荐

