取代价值和如果符合某些条件,则移位数据框

时间:2016-05-17 04:10:29

标签: regex r dplyr stringr

我从在线资源中删除了数据,以创建一个数据框(df1),其中有n行个人信息。它以单个字符串形式出现,我将这些单词拆分为适当的列。

90%的信息被正确格式化为数据框中的适当列数(6) - 然而,偶尔有一行数据,其中一个额外的单词位于第四个点字符串开头的单词。这些行现在有7列,并且与数据框中的其他所有内容相邻。

以下是一个例子:

Num Last-Name First-Name Cat. DOB Location

11 Jackson, Adam L 1982-06-15 USA
2 Pearl, Sam R 1986-11-04 UK
5 Livingston, Steph LL 1983-12-12 USA
7 Thornton, Mark LR 1982-03-26 USA
10 Silver, John RED LL 1983-09-14 USA


df1 = c(" 11 Jackson, Adam L 1982-06-15 USA",
    "2 Pearl, Sam R 1986-11-04 UK",
    "5 Livingston, Steph LL 1983-12-12 USA",
    "7 Thornton, Mark LR 1982-03-26 USA",
    "10 Silver, John RED LL 1983-09-14 USA")

您可以看到项目#10添加了额外的输入,颜色"RED"被插入到字符串的中间。

我开始运行使用的代码来评估第4个字中存在的字符数,如果它是3或更大(Cat.列中的每个值都是1-2个字符),我在数据框的末尾创建了一个新列,为其分配了值,如果没有值(即它的计算结果为FALSE),则输入NA。我确信我可能会在 ifelse(我个人的舒适区)中创建一个大型嵌套mutate语句,但我认为必须有一种更有效的方法来实现我的期望结果:

Num Last-Name First-Name Cat. DOB Location Color

11 Jackson, Adam L 1982-06-15 USA NA
2 Pearl, Sam R 1986-11-04 UK NA
5 Livingston, Steph LL 1983-12-12 USA NA
7 Thornton, Mark LR 1982-03-26 USA NA
10 Silver, John LL 1983-09-14 USA RED

我想找到字符串开头的第4个字是3个字符或更长的实例,将该字或值分配给数据框末尾的新列,并移动行中的相应值在左侧与其他数据行正确对齐。

3 个答案:

答案 0 :(得分:2)

这是一种更简单的方法:

input <- gsub("(.*, \\w+) ((?:\\w){3,})(.*)", "\\1 \\3 \\2", input, TRUE)
input <- gsub("([0-9]\\s\\w+)\\n", "\\1 NA\n", input, TRUE)

第一个gsub将颜色转换为字符串的末尾。第二个gsub利用未更改的行现在以日期和国家代码(不是国家代码和颜色)结束的事实,并简单地向它们添加“NA”。 / p>

IDEone demo

答案 1 :(得分:1)

我们可以使用#include <stdio.h> #define ccat(s, t, a, b) ((t)?(s a):(s b)) int main ( int argc, char **argv){ printf("%s\n", ccat("hello ", argc > 2 , "y'all", "you")); return 0; } 删除额外的子字符串

gsub

答案 2 :(得分:0)

使用strsplit代替正则表达式:

# split strings in df1 on commas and spaces not preceded by the start of the line
s <- strsplit(df1, '(?<!^)[, ]+', perl = T)

# iterate over s, transpose the result and make it a data.frame
df2 <- data.frame(t(sapply(s, function(x){
    # if number of items in row is 6, insert NA, else rearrange
    if (length(x) == 6) {c(x, NA)} else {x[c(1:3, 5:7, 4)]}
})))

# add names
names(df2) <- c("Num", "Last-Name", "First-Name", "Cat.", "DOB", "Location", "Color")

df2
#   Num  Last-Name First-Name Cat.        DOB Location Color
# 1  11    Jackson       Adam    L 1982-06-15      USA  <NA>
# 2   2      Pearl        Sam    R 1986-11-04       UK  <NA>
# 3   5 Livingston      Steph   LL 1983-12-12      USA  <NA>
# 4   7   Thornton       Mark   LR 1982-03-26      USA  <NA>
# 5  10     Silver       John   LL 1983-09-14      USA   RED