2016-12-15 4 views
0
head(df) 
    V1   V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 
1 1152652 1152652 0 0 2 -9 1 1 2 2 0 0 2 2 1 1 
2 1051495 1051495 0 0 2 -9 1 1 2 2 0 0 2 2 1 1 
3 1195877 1195877 0 0 2 -9 1 1 2 2 0 0 2 2 1 1 

Это df составляет около 200 000 строк. Я хотел бы сравнить 2 целых числа в 8-м столбце. Я попробовал конвертировать. Когда я использовал strsplit(), ситуация стала супер беспорядочной.Сравнение символов внутри одной колонки В R

Е.Г., Если я колонка V8:

V8 <- as.character(df$V8) 
test <- strsplit(V8, " ") 
head(test) 

[[1]] 
[1] "2" "2" 

есть более элегантный хотите сделать это? Меня интересует только восьмая колонка. Спасибо.

+0

Не совсем. Ваша колонка содержит два символа в одной строке - вам придется разбить ее каким-то образом перед сравнением. – thelatemail

ответ

1

Использование tidyr::separate, вы можете отделить V8 колонку на две колонки (т.е. V8a и V8b):

library(tidyr) 
df <- separate(df,V8,c("V8a","V8b")) 
     V1  V2 V3 V4 V5 V6 V7 V8a V8b V9 V10 V11 
1 1152652 1152652 0 0 2 -9 1 1 2 2 0 0 2 2 1 1 
2 1051495 1051495 0 0 2 -9 1 1 2 2 0 0 2 2 1 1 
3 1195877 1195877 0 0 2 -9 1 1 2 2 0 0 2 2 1 1 

Затем, вы можете сравнить их:

is_eq <- df$V8a == df$V8b 
##[1] TRUE TRUE TRUE 

данных:

df <- structure(list(V1 = c(1152652L, 1051495L, 1195877L), V2 = c(1152652L, 
1051495L, 1195877L), V3 = c(0L, 0L, 0L), V4 = c(0L, 0L, 0L), 
    V5 = c(2L, 2L, 2L), V6 = c(-9L, -9L, -9L), V7 = c("1 1", 
    "1 1", "1 1"), V8 = c("2 2", "2 2", "2 2"), V9 = c("0 0", 
    "0 0", "0 0"), V10 = c("2 2", "2 2", "2 2"), V11 = c("1 1", 
    "1 1", "1 1")), .Names = c("V1", "V2", "V3", "V4", "V5", 
"V6", "V7", "V8", "V9", "V10", "V11"), class = "data.frame", row.names = c(NA, 
-3L)) 
##  V1  V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 
##1 1152652 1152652 0 0 2 -9 1 1 2 2 0 0 2 2 1 1 
##2 1051495 1051495 0 0 2 -9 1 1 2 2 0 0 2 2 1 1 
##3 1195877 1195877 0 0 2 -9 1 1 2 2 0 0 2 2 1 1 
1

Я хочу оставить идею, с которой вы можете справиться с этой задачей для нескольких столбцов, поскольку набор данных содержит пару столбцов, которые содержат два числа соответственно. Я создал простые данные ниже. Здесь V1 и V2 содержат два числа. Поэтому я хотел сделать сравнение чисел для этих столбцов. Первый шаг - определить, какие столбцы содержат два числа. Между ними должно быть пространство. Используя эту идею, вы можете определить целевые столбцы. В grep() я выбрал первую строку данных и строки поиска, содержащие пробел. Затем я взял имена столбцов (т. Е. V1 и V2). Второй шаг состоял в том, чтобы разбить целевые столбцы на cSplit(). После разделения столбцов числа становятся числовыми, а не символами. На третьем шаге вы выбираете пару столбцов в lapply() и делаете простой расчет. Если два числа идентичны, вычитание должно возвращать 0. Вы можете использовать это для логической проверки и создать новый столбец с именем check, и вы выбираете только столбец. Затем вы создаете таблицу данных с cbind(). Наконец, вы хотите обновить имена столбцов ind (т. Е. V1 и V2).

library(dplyr) 
library(data.table) 
library(splitstackshape) 

mydf <- data.frame(V1 = c("1 1", "2 3", "3 3"), 
        V2 = c("10 11", "12 12", "13 13"), 
        V3 = 101:103, 
        stringsAsFactors = FALSE) 

# V1 V2 V3 
#1 1 1 10 11 101 
#2 2 3 12 12 102 
#3 3 3 13 13 103 

# Find columns which include two numbers. 
mydf[, grepl(pattern = "\\s", x = mydf[1, ])] %>% 
colnames -> ind 

# Prepare a data set splitting numbers in one column 
cSplit(mydf, splitCols = ind, direction = "wide", sep = " ") -> temp 

# Choose a pair of columns. Check if the subtraction generates 0. 
# If 0, two numbers are identical. If not, they do not match. 

lapply(ind, function(i){ 

    temp[, grep(i, x = names(temp)), with = FALSE] -> foo 
    foo[, check := foo[, 1, with = FALSE]- foo[, 2, with = FALSE] == 0] 
    foo[, 3, with = FALSE] -> foo 
    foo 
    }) -> temp 

# Create a data table 
do.call(cbind, temp) -> out 

# Update column names 
setnames(out, ind) 

#  V1 V2 
#1: TRUE FALSE 
#2: FALSE TRUE 
#3: TRUE TRUE 
Смежные вопросы