0

我使用了回答我之前问题的用户的 R 代码(请参阅此处: Split values of a column in a data frame by specific tag and add them as extra row)来实现以下目标:

df <- data.frame(var1 = c("A", "B", "C", "D", "E"),            

             var2 = c("test", "5 | 6", "X & Y", "M | N | O", "none"))

> df         
  var1          var2
1    A          test
2    B         5 | 6
3    C         X & Y
4    D     M | N | O
5    E          none


t1 <- c("", "|")[df$var1 %in% df$var1[grep("\\|", df$var2)]+1]

t2 <- c("", "&")[df$var1 %in% df$var1[grep("&", df$var2)]+1]

t1[which(t2 == "&")] <- "&"

df$var3 <- t1


> df
  var1          var2     var3
1    A          test     
2    B         5 | 6        |
3    C         X & Y        &
4    D     M | N | O        |
5    E          none     

我只是想知道是否有更好的方法,因为我真的想改进我的 R 编码方式。对我来说,这并不是一项简单的任务,但我愿意学习 :-)

4

4 回答 4

2

假设您的数据确实组织得很好,具有适当的间距等,您可以gsubsubstring.

df$var3 = substring(gsub("([a-zA-Z0-9 ])", "", df$var2), 1, 1)
df
#   var1      var2 var3
# 1    A      test     
# 2    B     5 | 6    |
# 3    C     X & Y    &
# 4    D M | N | O    |
# 5    E      none
  1. 对于您的搜索模式,查找所有字母、数字和空格,并将它们替换为空。
  2. 然后,将substring(or substr) 与startand stopas一起使用1

更新

假设 中可能有不同的标点符号,一种更通用的方法var2是:

gsub("[^[:punct:]]", "", df$var2)
# [1] ""   "|"  "&"  "||" ""  

同样, usingsubstr将允许您仅选择每个字符串中的第一个字符。

substr(gsub("[^[:punct:]]", "", df$var2), 1, 1)
# [1] ""  "|" "&" "|" "" 

如果您肯定只有这两个分隔字符,则可以将搜索模式从 更改[^[:punct:]][^\\||\\&]

在此更新的示例中,^(在方括号内)表示匹配这些字符之外的所有内容。

于 2012-07-17T11:51:18.897 回答
1

您可以改用它:

t3 <- rep("",length(df$var1))
t3[which(grepl("&",df$var2))] <- "&"
t3[which(grepl("\\|",df$var2))] <- "|"
df$var3 <- t3
于 2012-07-17T11:44:28.807 回答
0

我找到了另一种解决方案,它只在一行中对我有用:-)

library(stringr)

df$var3 <- str_extract(df$var2, "\\||&")

但是,我不得不说我不关心将 's 添加到找不到匹配项的代码。

感谢您提供的所有解决方案!确实很棒!

于 2012-07-17T13:11:18.757 回答
0
grepl("\\|",df$var2)
grepl("&",df$var2)

是相同的

df$var1 %in% df$var1[grep("\\|", df$var2)]
df$var1 %in% df$var1[grep("&", df$var2)]+1

所以你可以使用例如

ifelse(grepl("\\|",df$var2),'|','')
ifelse(grepl("&",df$var2),'&','')
于 2012-07-17T11:46:14.690 回答