我正在处理一个大型数据框,其中包含一个串联向量,该向量中包含几条信息。我需要提取这些值进行分析,这可以使用 substr() 函数来完成,但观察结果的长度不同,这使得这不理想。虽然我有一些工作代码,但数据集的大小意味着需要相当长的时间来处理,并且想知道是否有更好的方法。
例如8位数据点“97110770” 包含信息
但有些值是 9 位数字,例如“114123411” 将会有:
为了解决这个问题,我想到在较小的变量前面添加一个“0”,这样它们的长度就相同(时间值后面的数字一致,所以它可以正常工作)并想出了以下代码:
(数据框:
data
,感兴趣的向量:speakerid
)
congv <- vector(mode = "numeric")
memberidv <- vector(mode = "numeric")
chamberv <- vector(mode = "numeric")
for (i in 1:length(data$speakerid)) {
if(nchar(data$speakerid[i]) == 8) {
data$speakerid[i] = paste0("0", data$speakerid[i])
}
congv <- append(congv, substr(data$speakerid[i], 1, 3) )
memberidv <- append(memberidv, substr(data$speakerid[i], 4, 8))
chamberv <- append(chamberv, substr(data$speakerid[i], 9, 9))
}
data <- cbind(data, cong = congv, memberid = memberidv, chamber = chamberv)
data <- select(data, "memberid", "count", "chamber", "cong")
rm(list = c("congv", "memberidv", "chamberv"))
这可行,但是由于数据的大小(超过 100k 个观察值),它花费的时间比我想要的要长得多(因为我稍后可能需要包含更多数据),我想知道是否有更有效的方法这样做(也许不使用 for-if 循环?)
如果没有,我对 R 相当陌生,希望您能提供有关我的代码的任何其他提示,谢谢!
Example dataframe:
speakerid = c(97110770, 114123411, 93123770, 112123410, 93123770)
count = c(12, 3, 4, 0, 4)
data = data.frame(speakerid, count)
尝试使用
mapply
并使用 sprintf
添加前导零。
> cbind(data, `colnames<-`(mapply(substr, list(sprintf('%09d', data$speakerid)),
+ c(1, 4, 9), c(3, 8, 9)),
+ c('cong', 'memberid', 'chamber')))
speakerid count cong memberid chamber
1 97110770 12 097 11077 0
2 114123411 3 114 12341 1
3 93123770 4 093 12377 0
4 112123410 0 112 12341 0
5 93123770 4 093 12377 0
----
数据:
> dput(data)
structure(list(speakerid = c("097110770", "114123411", "093123770",
"112123410", "093123770"), count = c(12, 3, 4, 0, 4)), row.names = c(NA,
-5L), class = "data.frame")
这里有一个
tidyverse
选项,它添加前导零,分解字符串并在短短几行内创建新列,没有循环或中间变量:
library(tidyverse)
data %>%
mutate(sid = ifelse(speakerid < 1e8, paste0('0', speakerid), speakerid)) %>%
separate(sid, sep = c(4, 8), into = c('time', 'person', 'place'))
#> speakerid count time person place
#> 1 97110770 12 097 11077 0
#> 2 114123411 3 114 12341 1
#> 3 93123770 4 093 12377 0
#> 4 112123410 0 112 12341 0
#> 5 93123770 4 093 12377 0