我在向量中有数千个数字串,每个数字代表以语音为单位的音调实现(下降,上升,下降等)。举例说明:
Tones <- c("2222", "1411", "112", "815", "21111522")
我想为每个字符串获取的是一个可变性指数,
例如,对于&#34; 2222&#34;,变异性指数为0,因为字符串中的第一个数字等于第二个数字,第二个数字等于第三个数字,第三个数字等于最后一个数字。因此,可变性指数将是(0 + 0 + 0)/ 3 = 0。对于字符串&#34; 1411&#34;索引将是(1 + 1 + 0)/3=0.6666667因为&#34; 1&#34;不同于&#34; 4&#34;,&#34; 4&#34;不同于&#34; 1&#34;和&#34; 1&#34;等于&#34; 1&#34;。
我想我们必须从拆分字符串开始:
TonesSplit <- strsplit(Tones, split="")
给出一个列表,然后使用for
循环和if
子句来寻址列表切片中的单元格。我该怎么做才不知道。我非常感谢有关如何编程的建议。
答案 0 :(得分:3)
base
单线R解决方案:
vapply(Tones,function(x) length(rle(charToRaw(x))$lengths)-1,1)/(nchar(Tones)-1)
# 2222 1411 112 815 21111522
#0.0000000 0.6666667 0.5000000 1.0000000 0.4285714
一些解释:
charToRaw
我得到每个字符串的原始字节内容; rle
我得到了重复字符序列的数量。这些变化只是序列数少于一个; vapply
我将每个字符串应用于函数; nchar
我得到每个字符串的字符数。答案 1 :(得分:2)
这应该这样做:
library(dplyr)
Tones <- c("2222", "1411", "112", "815", "21111522")
TonesSplit <- lapply(strsplit(Tones, split=""), as.numeric)
sapply(TonesSplit, function(x){
sum(ifelse(x != dplyr::lag(x, 1), 1, 0), na.rm = T)/(length(x)-1)
})
[1] 0.0000000 0.6666667 0.5000000 1.0000000 0.4285714
在ifelse
中,我们使用dplyr::lag()
将每个分割数向量与向量[-1]进行比较,从而生成以NA
开头的新向量,然后给出{ {1}}或0
,具体取决于条件。然后我们对此向量求和,忽略1
,并将其除以NA
,这是对的数量。
length(x)-1
表明@nicola的解决方案要快得多:
microbenchmark