我在R中读取了一个包含n列的数据框(df< -read.csv(data,as.is = T)),其中一列是这样的char列:
df$qual
===========
1/5
12/17
...
0/3
9/14
我希望将此列转换为数字向量,仅保留每行的第1个元素。
df$qual
===========
1
12
...
0
9
我想有更简单的方法(想法欢迎!),但我尝试了一下:
sapply(df$qual,strsplit() ,simplify=T)
现在的问题是我如何/在哪里传递参数split =" /"这样有效吗? R帮助没什么帮助。
提前感谢,p。
答案 0 :(得分:4)
也许
sapply(strsplit(df$qual,split="/") , "[[", 1)
解释:strsplit
生成结果列表,即原始输入中每个字符元素的字符向量。 "[["
是调用索引运算符的简便方法,而1
表示将附加参数1
传递给[[
- 即取第一个元素。另外两种可能更透明的方法来做同样的事情:
sapply(strsplit(df$qual,split="/"), function(x) x[[1]])
或
sapply(strsplit(df$qual,split="/") , head, 1)
您最后可能需要考虑as.numeric()
。
答案 1 :(得分:2)
一个带有示例的小替代方案(到目前为止我一直在使用):
myvec <- c('1/5', '12/17', '0/3','111/03') #define a vector
sapply(myvec, function(x) { #using sapply
a <- gregexpr(pattern='/', x)[[1]][1] #find location of '/'
return(substring(x , 1, a-1)) #substring from start and up to 1 position before the '/'
} )
输出(如果您不喜欢名字,可以unname
:
1/5 12/17 0/3 111/03
"1" "12" "0" "111"
答案 2 :(得分:2)
你的标题和描述之间有一点点含糊不清,所以无论如何我都会分享这个。
问题1 ,关于如何使用sapply
提取每个列表的第一个元素已被@BenBolker充分解决。
问题2 ,关于如何将其他参数传递给sapply
似乎没有答案。对此的答案是您将附加参数作为点(...
)参数传递给sapply
。例如,你可以做到:
sapply(yourvec, strsplit, "/", fixed = FALSE)
在上文中,"/"
和“fixed = FALSE
”作为strsplit
中sapply
的附加参数传递。请注意,这是一种非常低效的方法,因为您遍历向量并单独拆分每个向量,而strsplit
本身已经被向量化。
如果您的问题确实是关于在分隔符之前提取第一部分的有效方法,我确实有一些建议:
选项1 :考虑使用stringi
。甚至拆分,转换为矩阵,并提取矩阵的第一列比我在基础R中提出的解决方案更快:
library(string1)
stri_split_fixed(myvec, "/", simplify = TRUE)[, 1]
选项2 :考虑将sub
与perl正则表达式一起使用:
sub("(?=/).*", "\\2", myvec, perl = TRUE)
选项3:首选vapply
至sapply
,并通过添加strsplit
帮助fixed = TRUE
:
vapply(strsplit(myvec, split = "/", TRUE), "[[", character(1L), 1)
如果您想比较每种方法的效率,请尝试使用更大的矢量,如下所示:
myvec <- c('1/5', '12/17', '0/3','111/03')
myvec <- c(replicate(25000, myvec))