2016-12-09 7 views
3

Я хотел бы получить помощь в моих поисках, чтобы выбрать части строки в определенных строках в r-кадре данных. Я проиллюстрировал некоторые фиктивные данные ниже (floyd), чтобы проиллюстрировать.Как выбрать шаблон строки с условиями в цикле [r]

В первой строке данных есть только 1 слово (его число да, но я обрабатываю все числа как символы/слова) для каждого столбца, но строки с 2 по 4 содержат более одного слова. Я хотел бы выбрать число в каждой строке/ячейке на основе позиции, переданной ему с помощью именованного вектора cool_floyd_position.

# please NB need stringr installed for my solution attempt! 

# some scenario data 
floyd = data.frame(people = c("roger", "david", "rick", "nick"), 
       spec1 = c("1", "3 5 75 101", "3 65 85", "12 2"), 
       spec2 = c("45", "75 101 85 12", "45 65 8", "45 87"), 
       spec3 = c("1", "3 5 75 101", "75 98 5", "65 32")) 

# tweak my data 
rownames(floyd) = floyd$people 
floyd$people = NULL 

# ppl of interest 
cool_floyd = rownames(floyd)[2:4] 

# ppl string position criteria 
cool_floyd_position = c(2,3,1) 
names(cool_floyd_position) = c("david", "rick", "nick") 

# my solution attempt 
for(i in 1:length(cool_floyd)) 
{ 
select_ppl = cool_floyd[i] 
string_select = cool_floyd_position[i] 

floyd[row.names(floyd) == select_ppl,] = apply(floyd[row.names(floyd) == select_ppl], 1, 
        function(x) unlist(stringr::str_split(x, " ")[string_select])) 
     } 

Я пытаюсь получить мою FLOYD dataframe, чтобы выглядеть следующим образом, когда выбирается второе слово для всех столбцов Давидов, третье слово для всех Рик колонн и первое слово для всех столбцов нарицательные (Роже столбцы должны просто оставаться такими, как есть)

my_target_df = data.frame(people = c("roger", "david", "rick", "nick"), 
         spec1 = c("1", "5", "85", "12"), 
         spec2 = c("45", "101", "8", "45"), 
         spec3 = c("1", "5", "5", "65")) 

row.names(my_target_df) = my_target_df$people 
my_target_df$people = NULL 

Большое спасибо!

ответ

3

Вот еще один вариант использования mapply

library(stringr) 
#convert the factor columns to character 
floyd[] <- lapply(floyd, as.character) 
#transpose the floyd, subset the columns, convert to data.frame 
# use mapply to extract the `word` specified in the corresponding c1 
#transpose and assign it back to the row in 'floyd' 
floyd[names(c1),] <- t(mapply(function(x,y) word(x, y), 
     as.data.frame(t(floyd)[, names(c1)], stringsAsFactors=FALSE), c1)) 
floyd 
#  spec1 spec2 spec3 
#roger  1 45  1 
#david  5 101  5 
#rick  85  8  5 
#nick  12 45 65 

где

раствор
c1 <- cool_floyd_position #just to avoid typing 
+1

@Sotos благодарит за редактирование. Я делал редактирование в одно и то же время :-) Плюс один для вашего хорошего решения – akrun

+1

heh ... да, я понял :) Спасибо – Sotos

+1

Thnx @akrun. Очень признателен. Извиняюсь, что я не сделал это быстро - наступали выходные и очень быстро укусил меня в пятницу днем. :) – CallumH

2

Вы можете попробовать сочетание sapply, чтобы выполнить итерацию по рамке данных, и mapply, чтобы извлечь nth word из каждой колонки. то есть,

library(stringr) 
df1 <- rbind(df[1,-1], sapply(df[-1,-1], function(i) mapply(word, i, cool_floyd_position))) 
rownames(df1) <- df$people 
df1 
#  spec1 spec2 spec3 
#roger  1 45  1 
#david  5 101  5 
#rick  85  8  5 
#nick  12 45 65 

Единственным недостатком этого решения является то, что people отображаются в виде rownames, а не одну колонку. Есть много способов сделать это столбец, то есть,

df1$people <- rownames(df1) 
rownames(df1) <- NULL 
df1[c(ncol(df1), 1:ncol(df1)-1)] 
# people spec1 spec2 spec3 
#1 roger  1 45  1 
#2 david  5 101  5 
#3 rick 85  8  5 
#4 nick 12 45 65 
+0

Привет , Thnx @Sotos. Я могу жить с проблемой rowname :). Я теряю первый столбец, хотя, когда я запускаю ваше решение, ну, мое редактирование его ... 'new_df = rbind (floyd [1, -1], sapply (floyd [-1, -1], function (i) mapply (stringr :: word, i, cool_floyd_position))) ' – CallumH

+0

Да, он отображается как последний столбец, но вы можете легко перенести его на передний план. Что-то вроде 'df1 <- df1 [c (4, 1, 2, 3)]' должно сделать это ... или более общий 'df1 [c (ncol (df1), 1: ncol (df1) -1)]' – Sotos

+0

Привет @Sotos. столбец spec1, который полностью исчезает. Не переходите к последней колонке. – CallumH

1

Tidyverse:

library(stringi) # you have this installed if you have stringr 
library(tidyverse) 

pick_pos <- function(who, x, lkp) { 
    if (who %in% names(lkp)) { 
    map_chr(x, ~stri_split_fixed(., " ")[[1]][lkp[[who]]]) 
    } else { 
    x 
    } 
} 

rownames_to_column(floyd, "people") %>% 
    mutate_all(funs(as.character)) %>% # necessary since you have factors 
    group_by(people) %>% 
    mutate_all(funs(pick_pos(people, ., cool_floyd_position))) %>% 
    data.frame() %>% 
    column_to_rownames("people") 

 Смежные вопросы

  • Нет связанных вопросов^_^