2017-11-16 9 views
3

행당 값이 다른 문자 열이 있습니다.다른 양의 값을 가진 큰 문자 열을 여러 열로 나누십시오.

다음
GoodForMeal %>% head(5) 
# A tibble: 5 x 1 
GoodForMeal                     
<chr> 
1 dessert': False, 'latenight': False, 'lunch': True, 'dinner': True 
2 dessert': False, 'latenight': False, 'lunch': True, 'dinner': True 
3 <NA> 
4 dessert': False, 'latenight': False, 'lunch': True, 'dinner': True 
5 dessert': False, 'latenight': False, 'lunch': True, 'dinner': True 

컬럼의 첫 번째 행의 dput()입니다 : 이것은 단지 작은 예입니다

structure(list(GoodForMeal = "dessert': False, 'latenight': False, 'lunch': True, 'dinner': True, 'breakfast': False, 'brunch': False}"), .Names = "GoodForMeal", row.names = c(NA, 
-1L), class = c("tbl_df", "tbl", "data.frame")) 

난 후 열 이름과 콜론 앞의 값과 값을 지정하려면 콜론을 해당 열의 값으로 사용하십시오.

예 :

I는 tidyr packadge 및 separatespread 기능을 시도
desert latenight lunch diner 
1 False False  True True 
2 False False  True True 
3 NA  NA  NA NA 
4 False False  True True 
5 False False  True True 

:

separate(GoodForMeal, c("key", "value"), sep = ":", extra = "merge") %>% spread(key, value) 

문제는 R은 결장 전에 모든 값을 분할하지 않고, 그냥 첫 번째 값.

그래서 결과는 다음과 같다 : 그 예에서처럼 보이는 키우면 있도록

GoodForMeal %>% str() 

Classes ‘tbl_df’, ‘tbl’ and 'data.frame': 4464 obs. of 2 variables: 
$ dessert': chr " False, 'latenight': False, 'lunch': True, 'dinner': False, 'breakfast': False, 'brunch': False}" " False, 'latenight': False, 'lunch': True, 'dinner': True, 'breakfast': False, 'brunch': False}" " False, 'latenight': False, 'lunch': False, 'dinner': False, 'breakfast': False, 'brunch': False}" " False, 'latenight': False, 'lunch': True, 'dinner': True, 'breakfast': False, 'brunch': False}" ... 
$ <NA> : chr NA NA NA NA ... 

모든 아이디어를 어떻게 값을 분할? THX

+0

[재현 가능한 예] (http://stackoverflow.com/questions/5963269)를 제공 할 수 있습니까? 귀하의 솔루션을위한 – Sotos

답변

1

당신이 제공 한 테스트 데이터 작업, 나는 식사 시간 키워드와 함께 ': 같은 문자의 열을 제거하기 위해 먼저 mutate를 사용합니다. 이렇게하면 여러 식사 시간을 구분하는 쉼표로 구분할 수 있습니다.

df <- structure(list(GoodForMeal = "dessert': False, 'latenight': False, 'lunch': True, 'dinner': True, 'breakfast': False, 'brunch': False}"), 
       .Names = "GoodForMeal", row.names = c(NA, -1L), 
       class = c("tbl_df", "tbl", "data.frame")) 

df %>% 
    mutate(GoodForMeal = trimws(gsub("[':]|dessert|lunch|dinner|latenight|brunch", 
            "", 
            GoodForMeal))) %>% 
    separate(GoodForMeal, 
      c("dessert", "latenight", "lunch", "dinner"), 
      ", ", 
      extra="drop") 

그것은 양보해야합니다 :이 유용 증명 희망

# A tibble: 1 x 4 
# dessert latenight lunch dinner 
# * <chr>  <chr> <chr> <chr> 
# False  False True True 

다음은 그림입니다.

0

이것은 우아한 해결책은 아니지만 오래 사용할 수 있습니다. 데이터를 좀 더 일반적으로 변경했습니다. 희망이 좋은 시작이 될 수 있습니다.

# i made some changes in the data; remove lunch entry in the 4th element and remove dessert in the 1st 
sampleData <- c("'dessert': False, 'latenight': False, 'lunch': True, 'dinner': True", 
      "'dessert': False, 'latenight': False, 'lunch': True, 'dinner': True", 
      NA, 
      "'dessert': False, 'latenight': False, 'dinner': True", 
      "'latenight': False, 'lunch': True, 'dinner': True") 

# [1] "'dessert': False, 'latenight': False, 'lunch': True, 'dinner': True" 
# [2] "'dessert': False, 'latenight': False, 'lunch': True, 'dinner': True" 
# [3] NA                 
# [4] "'dessert': False, 'latenight': False, 'dinner': True"    
# [5] "'latenight': False, 'lunch': True, 'dinner': True" 

# not sure if this is necessary, but jsut to clean the data 
sampleData <- gsub(x = sampleData, pattern = "'| ", replacement = "") 

# i'm a data.table user, so i'll jsut use tstrsplit 
# split the pairs within each elements first 
x <- data.table::tstrsplit(sampleData, ",") 

# split the header and the entry 
test <- lapply(x, function(x) data.table::tstrsplit(x, ":", fixed = TRUE)) 

# get the headers 
indexHeader <- do.call("rbind", lapply(test, function(x) x[[1]])) 

# get the entries 
indexValue <- do.call("rbind", 
         lapply(test, function(x){if(length(x) > 1){ return(x[[2]])}else{ return(x[[1]])} })) 

# get unique headers 
colNames <- unique(as.vector(indexHeader)) 

colNames <- colNames[!is.na(colNames)] 

# determine the order of the entries using the header matrix 
indexUse <- apply(indexHeader, 2, function(x) match(colNames, x)) 

# index the entry matrix using the above matching 
resA <- mapply(FUN = function(x,y) x[y], 
       x = as.data.frame(indexValue), 
       y = as.data.frame(indexUse)) 

# convert to data frame 
final <- as.data.frame(t(resA)) 

# rename columns 
colnames(final) <- colNames 

# should give something like this 
final 
# dessert latenight lunch dinner 
# False  False True True 
# False  False True True 
# <NA>  <NA> <NA> <NA> 
# False  False <NA> True 
# <NA>  False True True 
+0

THX. 작동하지만 위의 예 에서처럼 보이지 않습니다. – Banjo