0

我有一个如下所示的外部数据文件,没有分隔符:

PLAYER  TEAM STUFF1 STUFF2
Jim Smith NYY    100  200
Jerry Johnson Jr. PHI    100  200
Andrew C. James  STL  200  200
A. J. Williams   CWS 100  200
Felix Rodriguez   BAL 100  100

我怎样才能阅读这个文件?我正在考虑readLines在三个连续大写字母的任何序列之前使用和拆分字符串。但是,我不知道该怎么做。

如果只有团队名称的第一个字母大写怎么办?

下面是一个类似的文件,其中名称后跟一列数字。我可以使用以下代码读取这些数据:

        TEAM  STUFF1 STUFF2
        New York Yankees    100  200
        Philadelphia Phillies    100  200
        Boston Red Sox    200  200
        Los Angeles Angels    100  200
        Chicago White Sox    100  100
        Chicago Cubs    200  100
        New York Mets    200  200
        San Francisco Giants    100 300
        Minnesota Twins    100 300
        St. Louis Cardinals  200 300

这是读取第二个数据集的代码:

setwd('c:/users/mmiller21/simple R programs/')

my.data3 <- readLines('team.names.with.spaces.txt')

# split between desired columns

my.data4 <- do.call(rbind, strsplit(my.data3, split = "(?<=[ ])(?=[0-9])", perl = T))

# returns string w/o leading or trailing whitespace
# This function is not mine and was found on Stack Overflow    
trim <- function (x) gsub("^\\s+|\\s+$", "", x)

my.data5 <- trim(my.data4)

# remove header
my.data6 <- my.data5[-1,]

# convert to data.frame
my.data6 <- data.frame(my.data6, stringsAsFactors = FALSE)

my.data6[,2] <- as.numeric(my.data6[,2])
my.data6[,3] <- as.numeric(my.data6[,3])
my.data6
                      X1  X2  X3
1       New York Yankees 100 200
2  Philadelphia Phillies 100 200
3         Boston Red Sox 200 200
4     Los Angeles Angels 100 200
5      Chicago White Sox 100 100
6           Chicago Cubs 200 100
7          New York Mets 200 200
8   San Francisco Giants 100 300
9        Minnesota Twins 100 300
10   St. Louis Cardinals 200 300

谢谢你的任何建议。我更喜欢 base R 中的解决方案。

4

2 回答 2

1

这是一个满足您要求的简单解决方案。它基于通过空格进行标记和重构名称。它假定名称是唯一包含多个标记的字段。应该注意的是,间距可能不会被完美地保留,并且可能无法与嵌入的制表符而不是空格一起正常工作:

library(stringr)
lines = readLines("team.names.with.spaces.txt");
for (line in lines[2:length(lines)]) {
    toks = strsplit(str_trim(line), " +")[[1]];
    ntoks = length(toks);
    name = paste(toks[1:(ntoks-3)], collapse=' ');
    team = toks[ntoks-2];
    num1 = as.integer(toks[ntoks-1]);
    num2 = as.integer(toks[ntoks]);
    print(line)
    print(name)
    print(team)
    print(num1)
    print(num2)
}

我确实建议使用 str_trim() ,除非您的文件始终是干净构造的,在这种情况下,您可能能够删除 stringr 依赖。输出如下所示:

[1] "Jim Smith NYY    100  200"
[1] "Jim Smith"
[1] "NYY"
[1] 100
[1] 200
[1] "Jerry Johnson Jr. PHI    100  200"
[1] "Jerry Johnson Jr."
[1] "PHI"
[1] 100
[1] 200

作为替代方案,您可以使用 str_locate() 更稳定地处理名称中的多个空格或标点符号(使用逗号的连字符名称):

library(stringr)
x="Jerry Johnson Jr. PHI    100  200"
ndx = str_locate(x," +[A-Z]{3} +[0-9]+ +[0-9]+")[1]
name = substr(x,1,ndx-1);
于 2014-02-09T04:37:41.943 回答
0

这将在三个连续的大写字母之前拆分字符串:

setwd('c:/users/mmiller21/simple R programs/')

my.data3 <- readLines('player.names.with.spaces.txt')

strsplit(my.data3, split = "(?<=[ ])(?=[A-Z]{3})", perl = T)

我可能可以从那里得到其余的。尽管我仍然对仅将团队名称的第一个字母大写的情况下如何读取文件感兴趣。

这是上面代码的结果:

[[1]]
[1] "PLAYER  " "TEAM "    "STUFF1 "  "STUFF2"  

[[2]]
[1] "Jim Smith "      "NYY    100  200"

[[3]]
[1] "Jerry Johnson Jr. " "PHI    100  200"   

[[4]]
[1] "Andrew C. James  " "STL  200  200"    

[[5]]
[1] "A. J. Williams   " "CWS 100  200"     

[[6]]
[1] "Felix Rodriguez   " "BAL 100  100"      

如果某些团队名称包含三个大写字母,而其他团队名称包含两个大写字母,则这是一个解决方案,如下面的数据集:

PLAYER  TEAM STUFF1 STUFF2
Jim Smith NYY    100  200
Jerry Johnson Jr. TB    100  200
Andrew C. James  STL 200  200
A. J. Williams   TB 100  200
Felix Rodriguez   CWS 100  100

my.data3 <- readLines('player.names.with.spaces3.txt')

strsplit(my.data3, split = "(?<=[ ])((?=[A-Z]{2})|(?=[A-Z]{3}))", perl = T)

如果团队名称并非全是大写字母,与此数据集一样:

PLAYER  TEAM STUFF1 STUFF2
Jim Smith NYY    100  200
Jerry Johnson Jr. Phi    100  200
Andrew C. James  StL  200  200
A. J. Williams   CWS 100  200
Felix Rodriguez   Bal 100  100

通过使用多个拆分,以下代码似乎有效:

setwd('c:/users/mmiller21/simple R programs/')

my.data3 <- readLines('player.names.with.spaces2.txt')

my.data4 <- strsplit(my.data3, split = "(?<=[ ])(?=[0-9])", perl = T)

my.data5 <- do.call(rbind, my.data4[])
my.data5 <- my.data5[-1,]

# returns string w/o leading or trailing whitespace

trim <- function (x) gsub("^\\s+|\\s+$", "", x)

my.data6 <- trim(my.data5)

my.data7 <- strsplit(my.data6[,1], ' (?=[^ ]+$)', perl=TRUE)

my.data8 <- do.call(rbind, my.data7[])

my.data9 <- trim(my.data8)

my.data10 <- cbind(my.data9, my.data6[,2:3])
my.data10

结果如下:

     [,1]                [,2]  [,3]  [,4] 
[1,] "Jim Smith"         "NYY" "100" "200"
[2,] "Jerry Johnson Jr." "Phi" "100" "200"
[3,] "Andrew C. James"   "StL" "200" "200"
[4,] "A. J. Williams"    "CWS" "100" "200"
[5,] "Felix Rodriguez"   "Bal" "100" "100"
于 2014-02-08T23:46:02.083 回答