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

Este gl es de aproximadamente 200.000 filas. Me gustaría comparar los 2 enteros dentro de la octava columna. Intenté convertir. Cuando usé strsplit(), la situación se volvió muy complicada.

Por ejemplo, si tomo la columna V8:

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

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

¿Hay un deseo más elegante de hacer esto? Solo me interesa la octava columna. Muchas gracias.

r
0
Workhorse 15 dic. 2016 a las 05:59

2 respuestas

La mejor respuesta

Con tidyr::separate, puede separar la columna V8 en dos columnas (es decir, V8a y 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

Entonces, puede comparar estos:

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

Datos:

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
aichao 15 dic. 2016 a las 03:23

Quiero dejar una idea de que puede manejar esta tarea para varias columnas, ya que el conjunto de datos contiene un par de columnas que contienen dos números respectivamente. Creé unos datos simples a continuación. Aquí, V1 y V2 contienen dos números. Así que quería hacer la comparación de números para estas columnas. El primer paso es identificar qué columnas contienen dos números. Debe haber un espacio entre ellos. Con esta idea, puede identificar columnas de destino. En grep(), elegí la primera fila de los datos y busqué cadenas que contenían un espacio. Luego, recogí los nombres de las columnas (es decir, V1 y V2). El segundo paso fue dividir las columnas de destino con cSplit(). Una vez que dividió las columnas, los números se volvieron numéricos, no caracteres. En el tercer paso, elige un par de columnas en lapply() y realiza un cálculo simple. Si dos números son idénticos, la resta debe devolver 0. Puede usar esto para una verificación lógica y crear una nueva columna llamada check, y elige solo la columna. Luego, crea una tabla de datos con cbind(). Finalmente, desea actualizar los nombres de las columnas con ind (es decir, V1 y 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
1
jazzurro 15 dic. 2016 a las 13:39