R从列表元素创建一个热矢量

时间:2013-03-04 18:45:10

标签: r plyr

我正在尝试为输入文件处理一些字符串。首先,我将字符串从向量转换为列表,然后将其简化为唯一值。

接下来我想将每个列表元素中的单词转换为带有':1'分隔符的字符串。

我可以使用该函数处理单个列表元素但是当我尝试使用ldply中的plyr为整个列表执行此操作时,我只得到每个列表元素中的最后一个单词

以下是代码:

library(plyr)

df1 <- data.frame(id = seq(1,5,1), string1 = NA)
head(df1)
df1$string1[1] <- "This string is a string."
df1$string1[2] <- "This string is a slightly longer string."
df1$string1[3] <- "This string is an even longer string."
df1$string1[4] <- "This string is a slightly shorter string."
df1$string1[5] <- "This string is the longest string of all the other strings."

df1$string1 <- tolower(as.character(df1$string1))
df1$string1 <- gsub('[[:punct:]]',' ',df1$string1)
df1$string1 <- gsub('[[:digit:]]',' ',df1$string1)
df1$string1 <- gsub("\\s+"," ",df1$string1)

fdList1 <- strsplit(df1$string1, " ", df1$string1)
fdList2 <- lapply(fdList1, unique)

toString1 <- function(x){
string2 <- c()
#print(length(x[1][1]))
#print(x)
#print(class(x))
for(i in length(x)){
string2 <- paste0(string2, x[[i]], ":1 ", collapse="")
}
string2
}

df2 <- ldply(fdList2, toString1)
df2 

v1 <- toString1(fdList2[2])
v1

df2错误,我想为每个列表元素添加类似于v1的向量。

有什么建议吗?

2 个答案:

答案 0 :(得分:3)

解释为什么会这样:

您的问题toString1是问题所在:

toString1 <- function(x) {
    string2 <- c()
    for(i in length(x)) { 
        string2 <- paste0(string2, x[[i]], ":1 ", collapse="")
    }
    string2
}

toString1(fdList2[1])的情况下,您正在传递一个列表。因此,for-loop没有用处。如果您的功能是:

,它将起作用
toString1 <- function(x) {
    string2 <- paste0(x[[1]], ":1 ", collapse="")
}
o <- toString1(fdList2[2])

# [1] "this:1 string:1 is:1 a:1 slightly:1 longer:1 "

但是当你ldply时,你传递的不是列表(fdList2[2]),而是矢量(fdList2[[2]])。因此,在这种情况下,您的功能应该是:

toString1 <- function(x) {
    string2 <- c()
    for(i in 1:length(x)) { 
        string2 <- paste0(string2, x[i], ":1 ", collapse="")
    }
    string2
}
ldply(fdList2, toString1)

#                                                                   V1
# 1                                          this:1 string:1 is:1 a:1 
# 2                      this:1 string:1 is:1 a:1 slightly:1 longer:1 
# 3                         this:1 string:1 is:1 an:1 even:1 longer:1 
# 4                     this:1 string:1 is:1 a:1 slightly:1 shorter:1 
# 5 this:1 string:1 is:1 the:1 longest:1 of:1 all:1 other:1 strings:1 

请注意for循环中的length(x)更改为1:length(x),因为它必须循环遍历所有元素,x[[i]]再循环到x[i],因为它是一个向量。

希望这有帮助。

答案 1 :(得分:2)

为什么不在“fdList2”上使用sapply

> sapply(fdList2, paste0, ":1 ", collapse = "")
[1] "this:1 string:1 is:1 a:1 "                                         
[2] "this:1 string:1 is:1 a:1 slightly:1 longer:1 "                     
[3] "this:1 string:1 is:1 an:1 even:1 longer:1 "                        
[4] "this:1 string:1 is:1 a:1 slightly:1 shorter:1 "                    
[5] "this:1 string:1 is:1 the:1 longest:1 of:1 all:1 other:1 strings:1 "
> ## If you need a single column data.frame
> data.frame(V1 = sapply(fdList2, paste0, ":1 ", collapse = ""))
                                                                  V1
1                                          this:1 string:1 is:1 a:1 
2                      this:1 string:1 is:1 a:1 slightly:1 longer:1 
3                         this:1 string:1 is:1 an:1 even:1 longer:1 
4                     this:1 string:1 is:1 a:1 slightly:1 shorter:1 
5 this:1 string:1 is:1 the:1 longest:1 of:1 all:1 other:1 strings:1 

就此而言,如果这确实是您的目标,您可以进一步简化您的中间步骤。跳过“fdList1”和“fdList2”的创建,只需使用:

sapply(strsplit(df1$string1, " "), 
       function(x) paste0(unique(x), ":1 ", collapse = ""))